Reputation: 803
In my rails v4 app, users belong to a single group.
class User < ActiveRecord::Base
belongs_to :group
...
Each group can have many projects,
class Group < ActiveRecord::Base
has_many :projects
has_many :users
...
Each project can have many experiments, in a one to many relationship.
In my routes, I have:
resources :projects do
resources :experiments do
...
end
end
What I'd like to do is only allow users to access projects and experiments if the project has the same group_id as the user (i.e. if user enters a project id parameter in the projects#show route for a project outside of their group, it will not be displayed). Is there a clean way to implement this without having to do multiple checks in the view?
Upvotes: 0
Views: 1982
Reputation: 562
This is authorization problem, so, as for me, it's better to define what users can and can not see using any auhtorization library, not using routes or something like that. Because you will, for example, definitely want to find out should you display link on given group in views, which groups is available for current user and so on.
Take a look on cancancan
for example: https://github.com/CanCanCommunity/cancancan.
Upvotes: 1
Reputation: 649
Take a look at building a custom constraint based on Group membership:
http://guides.rubyonrails.org/routing.html#advanced-constraints
Extremely simple example (obviously, you'll need to match your project design):
class GroupConstraint
def initialize
@project = Project.find(params[:id])
@user = current_user
end
def matches?(request)
@user.groups.include?(@project.group)
end
end
Then in your routes:
resources :projects, constraints: GroupConstraint.new do
resources :experiments do
...
end
end
Upvotes: 3