2

그래서 레일스는 : habtm 관계를 통한 연결을 지원하지 않습니다. 거기에 레일스 2.x에서 이것을 추가 할 플러그인이 있지만 레일즈 3/에지를 사용하고 특정 모델에 대한 연관 만 필요합니다. 그래서 저는 Arel이라는 아름다움으로 나 자신을 그루터기를 털썩 내 렸습니다.레일스 3에서 has_and_belongs_to_many 중첩 된 동작 시뮬레이션

첫째, 모델 :

나는 특정 카드 세트에 속하는 모든 교훈을 얻고 싶은
class CardSet < ActiveRecord::Base 
    has_and_belongs_to_many :cards, :uniq => true 
end 

class Card < ActiveRecord::Base 
    has_and_belongs_to_many :card_sets, :uniq => true 
    has_many :learnings, :dependent => :destroy 
end 

class Learning < ActiveRecord::Base 
    belongs_to :card 
end 

=> 카드를 통해. 저를 (! 빌어 먹을, Arel이 아름답다) 제공

def learnings 
    c = Table(Card.table_name) 
    l = Table(Learning.table_name) 
    j = Table(self.class.send(:join_table_name, Card.table_name, CardSet.table_name)) 
    learning_sql = l.where(l[:card_id].eq(c[:id])).where(c[:id].eq(j[:card_id])).join(j).on(j[:card_set_id].eq(self.id)).to_sql 
    Learning.find_by_sql(learning_sql) 
end 

:

내가 내 CardSet 모델에서 지금까지 무엇을 가지고 오에 가까운입니다

SELECT  `learnings`.`id`, `learnings`.`card_id`, `learnings`.`user_id`, `learnings`.`ef`, `learnings`.`times_seen`, `learnings`.`next_to_be_seen`, `learnings`.`interval`, `learnings`.`reps`, `learnings`.`created_at`, `learnings`.`updated_at`, `card_sets_cards`.`card_set_id`, `card_sets_cards`.`card_id` FROM  `learnings` INNER JOIN `card_sets_cards` ON `card_sets_cards`.`card_set_id` = 1 WHERE  `learnings`.`card_id` = `cards`.`id` AND `cards`.`id` = `card_sets_cards`.`card_id` 

내가 목표로한다면 명세서의 FROM 부분에있는 cards 테이블을 추가하기 만하면됩니다.

그리고 내 질문이 있습니다. 저는 Arel 소스를 살펴 보았습니다. 그리고 내 인생에서 나는 다른 테이블을 추가하는 방법을 알 수 없습니다.

sidenote로, Arel (일반적으로 Arel :: Relation을 반환하는)에서 결과를 실행하는 더 좋은 방법이 있습니까? ActiveRecord를 통해, sql로 렌더링하고 find_by_sql 내가하고있는 것처럼?

답변

0

이 내가 위에 쓴 것보다 더 쉽게, 후 직접 쿼리.

는 일명는 CardSet 모델에서 중첩 된 HABTM 스텁하려는 경우 : 다음

class CardSet < ActiveRecord::Base 

    has_and_belongs_to_many :cards, :uniq => true 

    def learnings 
    Learning.joins(:card).where(:cards => { :id => self.card_ids }) 
    end 
end 

이 의지 같은 쿼리 :

has_many :learnings, :through => :cards 

가 다음 동작을 시뮬레이션하기 위해 이것을 사용할 수 있습니다

일 :

CardSet.first.learnings 
0

나는 Arel에 익숙하지 해요,하지만 처리하지 않습니다 : 당신이 구축 할 필요가 없습니다 레일 Arel을 캡슐화하는 방법을 배웠습니다

l.includes(:card) 
+0

그와 관련된 카드와 관련된 것보다는 모든 학습을 끌어 올 것입니다. card_set (a.k.a., 중첩 된 habtm). – bouchard