Rails ActiveRecord 中作用域下的复杂关联查询

4
我有以下作用域,我知道它不是最优解:
scope :event_stream_for, lambda{ |user|
  where("target_id in (?) and target_type = ?", user.events.collect(&:id), "Event")
}

这将创建3个查询。我该如何进行优化?

或者,我如何将整个SQL语句放在作用域的lambda中,例如:

SELECT * FROM activities WHERE target_type =='Event' AND target_id IN (SELECT DISTINCT id FROM events WHERE (host_id == user.id OR invitee_id == user.id))

谢谢

2个回答

4
假设用户有许多事件,每个事件都属于一个用户。
scope :event_stream_for, lambda{ |user
  joins(:events). # or joins("LEFT JOIN events ON events.user_id = users.id").
  where(["target_type=?", "Event"]) 
}

这将运行一个查询。我还没有用你的表测试过我的代码,但它应该类似工作。

----------------------- 根据您编辑的问题 -------------------

SELECT * FROM activities WHERE target_type =='Event' AND target_id IN (SELECT DISTINCT id FROM events WHERE (host_id == user.id OR invitee_id == user.id))

这与 ActiveRecord Relation 有关,http://railscasts.com/episodes/239-activerecord-relation-walkthrough?view=asciicast

Activity.
select("*,distinct events.id AS events_id").
joins("events ON (events.host_id = #{user.id} OR events.invitee_id = #{user.id}").
where(:target_type => 'Event')

尝试在控制台上执行此代码,如果有效,则可以简单地将其更改为“scope”。 因为我不确定您想要做什么,所以您可能需要进行某些调整。

谢谢你的回答。我的user.events实际上是在寻找那些events.host_id == user.id或者events.invitee_id == user.id的事件。有没有Rails的方法可以做到这一点? - AdamNYC

1

这个怎么样?

scope :event_stream_for, lambda{ |user|
  where("target_id in (SELECT DISTINCT id FROM events WHERE (host_id == ? OR invitee_id == ?) and target_type = ?", user.id, user.id, "Event")
}

这只是重新排列您已经拥有的内容,但它应该将您减少到一个查询,因为它不使用代码中的关联。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接