Search code examples
ruby-on-railscancan

Ruby on Rails: Cancan - Restrict Child Creation


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.


Solution

  • 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.