模拟has_and_belongs_to_many嵌套在Rails 3中的行为

所以Rails不支持:通过关系进行关联。 有插件可以为Rails 2.x添加它,但我使用的是Rails 3 / Edge,只需要一个特定模型的关联。 所以我以为我会用Arel的美丽把自己弄得一团糟。

一,型号:

class CardSet  true end class Card  true has_many :learnings, :dependent => :destroy end class Learning < ActiveRecord::Base belongs_to :card end 

我希望获得属于特定卡片组的所有学习内容:through => cards。

这是我目前在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 

这给了我(该死的,Arel很漂亮!):

 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源代码,而对于我的生活,我无法弄清楚如何添加另一个表格。

作为旁注,是否有更好的方法从Arel(通常返回Arel :: Relation,我不想要)运行结果通过ActiveRecord,而不是渲染到sql并使用find_by_sql运行查询,因为我是在做什么?

我不熟悉Arel,但不会处理:

 l.includes(:card) 

在我了解了Rails如何封装Arel以便您不需要直接构建查询之后,这比我上面写的更容易。

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

 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