문제

나는 다형성 협회를 사용하여 프로젝트에서 의견을 추적하고 있습니다. 모든 매우 간단한 것들.

내가 가진 문제는 다형성 협회를 기반으로 쿼리하는 것입니다. 주석 모델에서 다시 소유자에게 가입하는 것입니다.

그래서 ...

주석 모델이 있습니다

class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true
end

포럼 토픽 모드 :

class ForumTopic < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

지금은 중요하지 않은 몇 가지 다른 "댓글 가능한"모델이 있습니다. 이 모든 것이 작동합니다.

내가하려고하는 것은 지정된 조건을 가진 포럼 주도에 속하는 모든 의견을 찾는 것입니다 (이 경우 'feactured'== true).

파인더를 사용하여 모델에 합류 할 때 :

@comments = Comment.find(:all 
            :joins => :commentable
            :conditions => ["forum_topics.featured = ? ", true] 
            )

다음 오류를받습니다.

다형성 연관성을 간절히로드 할 수 없습니다 : 주석

AR 사용 "include syntax":

@comments = Comment.find(:all 
            :include => :forum_topics
            :conditions => ["forum_topics.featured = ? ", true] 
            )

보고:

'Forum_Topics'라는 협회는 발견되지 않았습니다. 아마도 당신은 그것을 잘못 뽑았습니까?

협회 이름 대신 테이블 이름으로 가입하려고하면 (기호 대신 문자열) :

@comments = Comment.find(:all,
            :joins => "forum_topics",
            :conditions => ["forum_topics.featured = ? ", true] 
            )

내가 참조:

mysql :: 오류 : 알 수없는 테이블 '댓글': 댓글을 선택하십시오. 댓글에서 forum_topics where (forum_topics.featured = 1)*

(여기서 기본 쿼리의 구문이 완전히 꺼져 있고 조인이 모두 누락 된 것을 볼 수 있습니다).

내가하고있는 일이 가능하고 필요한 결과를 달성 할 수있는 다른 방법이 있는지 확실하지 않지만 그와 같은 것 같습니다. ~해야 한다 가능해야합니다.

어떤 아이디어? 내가 놓친 것이 있습니까?

도움이 되었습니까?

해결책

아르!

나는 문제를 발견했다고 생각합니다.

가입 할 때 :

@comments = Comment.find(:all,
        :joins => "forum_topics",
        :conditions => ["forum_topics.featured = ? ", true] 
        )

당신은 전체 가입이 필요합니다!

:joins => "INNER JOIN forum_topics ON forum_topics.id = comments.commentable_id",

항상 멋진 것을 참조하십시오.http://guides.rubyonrails.org/active_record_querying.html#joining-tables

다른 팁

오래된 질문이지만 다형성과 함께 특정 유형에 대한 직접적인 연관성을 설정함으로써이를 달성하는 더 깨끗한 방법이 있습니다.

#comment.rb
class Comment < ActiveRecord::Base

  belongs_to :commentable, polymorphic: true
  belongs_to :forum_topics, -> { where( comments: { commentable_type: 'ForumTopic' } ).includes( :comments ) }, foreign_key: 'commentable_id'

  ...

end

그런 다음 통과 할 수 있습니다 :forum_topics 에게 includes 지저분한 가입의 필요성을 없애기 :

@comments = Comment
  .includes( :forum_topics )
  .where( :forum_topics => { featured: true } )

그런 다음 쿼리를 범위로 옮겨서 더욱 정리할 수 있습니다.

#comment.rb
class Comment < ActiveRecord::Base

  ...

  scope :featured_topics, -> { 
    includes( :forum_topics )
    .where( :forum_topics => { featured: true } ) 
  }

  ...

end

당신이 단순히 할 수 있도록 떠납니다

@comments = Comment.featured_topics

조건부와 레일 3+가 필요합니다

많은 사람들이 답과 의견으로 그것을 암시했지만, 내가 여기에 착륙하고 철저히 읽지 않으면 나 자신을 포함한 사람들이 넘어 질 것이라고 생각했습니다.

따라서 조건부를 포함하여 적절한 답변이 있습니다. 물론 필요한.

@comments = Comment.joins( "INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id" )
                   .where( comments:     { commentable_type: 'ForumTopic' } )
                   .where( forum_topics: { featured:         true         } )

모두, 특히 @jits, @peter 및 @prograils의 의견에 감사드립니다.

"주석"을 사용하여 연관성이있는 다른 모델을 소개 한 후에 허용 된 솔루션은 작동하지 않습니다. Commentable_id는 독특하지 않으므로 잘못된 주석을 검색하기 시작합니다.

예를 들어:

의견을 받아들이는 뉴스 모델을 추가하기로 결정했습니다 ...

class News < ActiveRecord::Base
   has_many :comments, :as => :commentable
end

이제 1의 ID가있는 Forum_Topic에 댓글을 달고 쿼리를 사용하여 1의 ID가있는 뉴스 기사에 댓글을 달면 두 개의 레코드를 다시받을 수 있습니다.

:joins => "INNER JOIN forum_topics ON forum_topics.id = comments.commentable_id"

당신은 아마도 당신의 조건 중 하나로 댓글 가능한 _type를 제공함으로써 문제를 해결할 수 있지만, 이것이이 문제에 접근하는 가장 좋은 방법이라고 생각하지 않습니다.

나는이 게시물을 발견했고 그것은 내 솔루션으로 이끌었다. Commentable_type를 내 조건 중 하나로 사용하지만 대신 왼쪽 외부 조인을 사용합니다. 이렇게하면 댓글이없는 포럼 주제가 포함됩니다.

LEFT OUTER JOIN `comments` ON `comments`.`commentable_id` = `forum_topics`.`id` AND `comments`.`commentable_type` = 'ForumTopic'

아래에서 일하도록 확인했습니다 레일 5:

Solution 1:

@comments = Comment
              .where(commentable_type: "ForumTopic")
              .joins("INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id")
              .where(forum_topics: {featured: true})
              .all

또는

Solution 2:

@comments = Comment
              .joins("INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id AND comments.commentable_type = 'ForumTopic'")
              .where(forum_topics: {featured: true}).all

원시 SQL 구문에주의하십시오 : 백 티크가 허용되지 않습니다. 보다 http://guides.rubyonrails.org/active_record_querying.html#joining-tables .

원시 SQL 구문이 적은 솔루션 1을 개인적으로 선호합니다.

레일에는 기본적으로 다형성 결합이 포함되어 있지 않지만이 보석은 다형성 관계를 쉽게 결합시키는 데 도움이됩니다. https://github.com/jameshuynh/polymorphic_join

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top