2017-12-02 15 views
3

私のプロジェクトでは投稿クラスがあります。投稿クラスは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

ありがとう、私は上記のコードを試しましたが、それは私が望むように私を助けていません。 最初に私は "いいえそのような列:parents.status"と言っていました - 私は、アソシエーションに参加するのを忘れました それから、 '.joins(:parent)'を追加し、結合されたテーブルの正しい名前を使用する '' where(parent_posts:...) 'の部分。 これは私がもう一度突っ込んだところです: 'join(parent::user) 'を使っても' undefined method _reflect_on_association for nil:NilClass'を得ました あなたのアイデアがどう助けてくれるのか見ていますが、最初に他の問題を解決する。私は進捗状況を記します。 –

+0

お手伝いが必要な場合は教えてください。 –