Cancancan - 定义:使用关联创建

问题描述 投票:0回答:2

我的 Ruby on Rails 应用程序遇到以下情况:

我有一个包含帖子的博客。每个帖子可以有 1 到 n 作者,并且每个帖子都与多个评论相关联:

class Post < ApplicationRecord
    has_many :comments, dependent: :destroy
    has_many :authors

class Comment < ApplicationRecord
    belongs_to :post

我正在使用 CanCanCan 进行授权。目前,每个人都可以对帖子发表评论。我想通过在我的

lock_comments
模型上引入
post
属性并相应地更改授权来更改此设置,使其功能如下:

  • 如果用户未登录,则允许评论
    :create
    如果其父帖子上的
    lock_comments
    为假
  • 如果用户已登录,则允许评论
    :create
    如果其父帖子上的
    lock_comments
    为假,或者登录用户是该帖子的作者之一

基本上,作者应该能够禁用对其文章的评论,但他们仍然应该能够对自己的文章发表评论,即使其他人的评论被禁用。

我在这里有点不知所措,在文档中找不到任何内容。我必须如何定义我的

Ability
才能使其发挥作用?

ruby-on-rails ruby-on-rails-6 cancancan
2个回答
1
投票

我认为您无法在“能力”中执行此操作,因为当您尝试访问

create
时,您不知道父帖子是什么。如果
create_comment
PostsController
方法,你可以这样做...

can :create_comment, Post do |post|
  !post.lock_comments || user.in?(post.authors)
end

但是如果它是

create
中的
CommentsController
,您需要使用
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

0
投票

我们也一直在努力解决如何轻松配置这样的功能,并找到了使用 额外参数 的解决方案,您可以将其与

can
can?
函数一起使用。这样您就可以传入可以执行必要检查的父对象。

那么在检查授权时,您的解决方案将变成这样:

can? :create, Comment.new, @post

然后能力配置看起来像这样:

can :create, Comment do |comment, post|
  !post.lock_comments || user.in?(post.authors)
end
© www.soinside.com 2019 - 2024. All rights reserved.