Таким образом, у Rails нет поддержки: через ассоциации через отношения habtm. Существуют плагины, которые добавят это в Rails 2.x, но я использую Rails 3 / Edge, и мне нужна ассоциация только для одной конкретной модели. Поэтому я решила, что сама поставлю в тупик красоту Ареля.
Во-первых, модели:
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
Я хочу получить все уроки, которые относятся к определенному набору карт: 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
что дает мне (блин, Арел прекрасна!):
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`
, который очень близок к тому, к чему я стремлюсь - просто нужно добавить в таблицу cards
в части FROM оператора.
И вот мой вопрос: я просмотрел исходник Арела, и на всю жизнь я не могу понять, как добавить в другую таблицу.
Как sidenote, есть ли лучший способ запустить результат из Arel (который обычно возвращает Arel :: Relation, который я не хочу) через ActiveRecord, кроме рендеринга в sql и выполнения запроса с find_by_sql как Я делаю?