2017-12-02 57 views
3

在我的项目中,我有一个Post类,它可以是其他帖子的评论,其中self-join。除了其他的规则,我想启用它属于“发布”后的评论通过CanCanCan规则中的自引用关联进行过滤

我用下面的宝石帖子:

gem 'rails', '5.0.6' 
gem 'cancancan', '2.1.2' 

下面是模型和能力类

class Post < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :parent, class_name: 'Post', optional: true 
    has_many :comments, class_name: 'Post', foreign_key: 'parent_id', dependent: :destroy 
end 

class User < ActiveRecord::Base 
    has_many :posts 
end 

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    can :read, Post, parent: { status: %w(published), user: { id: user.id } } 
    end 
end 

我写了一些RSpec测试,他们都应该根据上面的规则通过。

RSpec.describe Ability do 
    subject(:ability){ Ability.new(user) } 

    let!(:user) { User.create } 
    let!(:commenter) { User.create } 
    let!(:post) { Post.create(user: user, parent: nil, status: 'published') } 
    let!(:comment) { Post.create(user: commenter, parent: post) } 

    # for individual objects it works 
    it { is_expected.not_to be_able_to :read, post } # pass 
    it { is_expected.to be_able_to :read, comment } # pass 

    # for accessible by query it fails 
    it { expect(Post.accessible_by(ability)).not_to include post } # pass 
    it { expect(Post.accessible_by(ability)).to include comment } # fail 
end 

当我运行RSpec测试时,最后一个失败。如果您检查SQL日志,您可以看到它创建了正确的JOINS,但它有一个错误的WHERE语句。

SELECT (...) 
FROM "posts" 
LEFT OUTER JOIN "posts" "parents_posts" ON "parents_posts"."id" = "posts"."parent_id" 
LEFT OUTER JOIN "users" ON "users"."id" = "parents_posts"."user_id" 
WHERE "posts"."status" = 'published' 
AND "users"."id" = ? 

你能帮我吗?这是CanCanCan中的错误还是我错误地使用了hash syntax

回答

0

好吧,我不知道你是否可以解决这个问题,但我会尽力帮助你。

def initialize(user) 
    can :read, Post, id: Post.where(parent: { status: 'published', user: { id: user.id }) } 
end 

试试这个,告诉我什么样的退货给你。

+0

谢谢,我试过上面的代码,但它没有帮助我,我希望的方式。 起初,我有一个SQL错误告诉我“没有这样的列:parents.status” - 我想我们忘了加入协会 然后我添加了'.joins(:parent)'并且必须改变where部分到'where(parent_posts:...)'为连接表使用正确的名称。 这就是我再次卡住的地方:即使我使用了'连接(父:用户)',我也得到了'undefined method _reflect_on_association for nil:NilClass'' 所以我看到你的想法是怎样帮助我的,但是我有首先解决其他问题。我会发布我的进度。 –

+0

好的,告诉我你是否需要帮助。 –