2017-12-02 1 views
3

내 프로젝트에는 self-join 인 다른 게시물에 대한 의견 일 수있는 게시물 클래스가 있습니다. 모델과 기능 클래스CanCanCan 규칙의 자기 참조 연결에 의한 필터

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 
은 여기

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

: 다른 규칙 옆에, 나는

가 나는 다음과 보석을 사용하여 주석으로는 '공개'포스트에 속하는 게시물을 사용하려면

일부 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

감사합니다. 위 코드를 시도했지만 희망 한 방식으로 도움을주지 못했습니다. 처음에 나는 "no such column : parents.status"라고 말하면서 SQL 에러를 보았습니다 - 우리는 협회에 가입하는 것을 잊었습니다. 그럼'.joins (: parent)'를 추가하고 어디에 조인 된 테이블에 대해 올바른 이름을 사용하려면'where (parent_posts : ...)'부분을 사용하십시오. 그게 내가 다시 붙어있는 지점입니다.'join (parent : : user) '을 사용하더라도'undefined method _reflect_on_association for nil : NilClass'이 있습니다. 여러분의 아이디어가 어떻게 도움이되는지 알지만, 다른 문제를 먼저 해결할 수 있습니다. 진행 상황을 게시합니다. –

+0

네가 도움이 필요하면 말해줘. –