This app has the structure of users have many organizations through memberships.
class User < ApplicationRecord
has_many :memberships, dependent: :destroy
has_many :organizations, through: :memberships
....
end
class Membership < ApplicationRecord
belongs_to :organization, touch: true
belongs_to :user, counter_cache: true
..
end
class Organization < ApplicationRecord
has_many :memberships, dependent: :destroy
has_many :members, through: :memberships, source: :user
...
end
The Organization can be destroyed by owners, attribute on memberships, from there call backs will take care of destroying associations.
There are before_actions that check user/organizations associations exists. So the moment the user hits a url with an organization that has been deleted, they would be redirected. But this seems wrong.
My question is while the current_user would follow the controller action redirect. How should the other users be handled? Should they hit the before_actions and let those redirects handle it? Can an after_destroy call back handle this; that seems like breaking the MVC pattern tho and then you have to deal with if the user is "on" that organization or another.
Hell has this been discussed and this has a name that I'm not aware of.
Much appreciated.
EDIT: Controller checks:
class Organizations::BaseController < ApplicationController
before_action :restrict_user_by_role
protected
def restrict_user_by_role
if organization_set?
if !member?
flash[:warning] = t("restricted_roles")
redirect_to redirect_path
elsif !current_membership.can_view_organization?
flash[:warning] = t("restricted_roles")
redirect_to redirect_path
end
else
id = params[:parm_passed]
unless Membership.current_member_check(id).exists?
flash[:warning] = t("restricted_roles")
refresh_or_redirect_to redirect_path
return
else
organization = Organization.find_by(id: id)
set_organization(organization)
@organization = current_organization
end
end
end
end
organization_set? current_membership member? are all concerns that are set with each request, while can_view_program?, Membership.current_member_check(id).exists? are authorization checks on the model record.
This is just some of the checks, but the basic idea that is used.
Looks like your
restrict_user_by_rolemake few things (non SRP). It should only check authorization rule and redirect if it fails. It shouldn't set instance variables. If before filter redirect somewhere, main action is not executedTo simplify your code make 3 checks: presence of current user, presence of current organization, ownership of current organization by current user. If one of these conditions is false — redirect user