2

因此,Rails不支持:通過habtm關係通過關聯。有些插件會爲Rails 2.x增加這個功能,但是我使用Rails 3/Edge,並且只需要關聯一個特定的模型。所以我認爲我會用Arel的美麗將自己打倒。模擬has_and_belongs_to_many通過Rails 3中的行爲嵌套

一,型號:

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 

我想這屬於一個特定的卡組中的所有學習收穫,:通過=>卡。

這是我到目前爲止在我CardSet模型:

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 

這給了我(該死,阿雷爾是美麗的!):

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源代碼,對於我的生活,我無法弄清楚如何添加到另一個表中。

作爲一個旁註,是否有更好的方式通過ActiveRecord運行Arel(通常返回Arel :: Relation,我不想要)的結果,除了渲染到sql並使用find_by_sql運行查詢我正在做什麼?

回答

0

這比我上面寫的更容易,以後我學會了Rails這樣封裝阿雷爾,這樣你就不需要建直接查詢。

如果你想存根嵌套的habtm在CardSet模型,又名:

has_many :learnings, :through => :cards 

,那麼你可以用它來模擬行爲:

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 

再這樣意志查詢工作:

CardSet.first.learnings 
0

我不熟悉阿雷爾,但是那會不會處理:

l.includes(:card) 
+0

這將拉動所有的學習,而不僅僅是與卡相關聯的card_set(又名,嵌套habtm)。 – bouchard 2010-10-06 21:40:57