I'm on Rails 4 with the Cancan gem. I have three models relevant to this problem:
Users:
has_many :submissions
has_many :submission_details, through: :submissions
Submissions:
belongs_to :user
has_many :submission_details
SubmissionDetails
belongs_to :submission
A user can create a new submission, then its child submission details. A user can't edit submissions/submission details that do not belong to him/her, and a user should not be able to add new submission details to a submission that is not owned by him/her (through :user_id
). Routing:
resources :submissions do
resources :submission_details
end
So, here is my question. I've been able to restrict a person from editing submission details that do not belong to him or her (through its parent submission :user_id
column):
can [:show, :update, :create], SubmissionDetail, submission: {user_id: user.id}
However, this does not work if a user tries to create a new submission detail to a parent submission that does not belong to him/her. Like, if a person changes the parent id in the URL:
http://localhost:3000/submissions/23/submission_details/new
I assume this is because the submission detail has not been created yet to know what the parent id is in the table (even though it is in the URL). Ideally, I would want the person to be instantly turned away from this "new submission detail" page if he/she does not own the parent submission in the URL. Any advice is appreciated.
The trick is to load the submission before creating the submission detail
submission = Sumbmission.find(params[:submission_id])
submission_detail = submission.detail.build(params[:submission])
authorize! :create submission_detail
submission_detail.save
To riderect the user away see Exception Handling . I would implement some general ridirect strategy to the index page, no matter when an authorize happened. You shouldn't be to chatty about the reasons of authorization restricts.