I have the following situation in my Ruby on Rails application:
I have a blog with posts. Each post can have 1 to n authors, and each post is associated with several comments:
class Post < ApplicationRecord
has_many :comments, dependent: :destroy
has_many :authors
class Comment < ApplicationRecord
belongs_to :post
I am using CanCanCan for authorization. Currently everyone is able to create comments on a post. I want to change this by introducing a lock_comments-attribute on my post model, and changing the authorization accordingly, so that it functions as follows:
:create if lock_comments on it's parent post is false:create if lock_comments on it's parent post is false, OR the logged in user is one of the authors of the postBasically the authors should be able to disable comments on their articles, but they should still be able to write comments on their own articles, even if the comments are disabled for others.
I am a bit at a loss here and could not find anything in the documentation. How do I have to define my Ability for this to work?
I don't think you can do this in Ability because at the time you're trying to access create you don't know what the parent post is. You COULD do this if create_comment was a PostsController method...
can :create_comment, Post do |post|
!post.lock_comments || user.in?(post.authors)
end
But if it's create in a CommentsController you'd need to do this with a before_action
class CommentsController < ApplicationController
before_action :create_allowed, only: [:create]
private
def create_allowed
post = Post.find(params[:comment][:post_id])
return if post && (!post.lock_comments || current_user.in?(post.authors))
flash[:error] = 'You are not allowed to do this'
redirect_to root_path
end
end