我有一个关系表:
create_table "animal_friends", :force => true do |t|
t.integer "animal_id"
t.integer "animal_friend_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "status_id", :default => 1
end
将动物与其他动物联系起来。在 SQL 中检索关联的最佳方法是:
SELECT animals.*
from animals join animal_friends as af
on animals.id =
case when af.animal_id = #{id} then af.animal_friend_id else af.animal_id end
WHERE #{id} in (af.animal_id, af.animal_friend_id)
而且我找不到用这个在rails中创建适当的has_many关系的方法。显然,没有办法为 has_many 提供加入条件。
我目前正在使用 finder_sql :
has_many :friends, :class_name => "Animal", :finder_sql => 'SELECT animals.* from animals join animal_friends as af on animals.id = case when af.animal_id = #{id} then af.animal_friend_id else af.animal_id end ' +
'WHERE #{id} in (af.animal_id, af.animal_friend_id) and status_id = #{Status::CONFIRMED.id}'
但是这种方法有一个很大的缺点,就是打破了activerecord的魔法。例如 :
@animal.friends.first
将无限制地执行finder_sql,获取数千行,然后获取数组的第一个(并失去几个宝贵的秒/请求)。
我想这是 AR 中缺少的功能,但我想先确定一下 :) 谢谢