【问题标题】:how to intersect two associations in arel?如何在 arel 中相交两个关联?
【发布时间】:2013-03-01 19:53:56
【问题描述】:

我有一个带有此关联的项目模型,该关联描述了已接受(状态)的团队成员

Class Project < ActiveRecord::Base
   has_many :participants, :through => :team_members, :source => :user, :conditions => ['team_members.status = ?', TeamMember::STATUS[:accept]]

我有一个包含参与者的活动模型

Class Activity < ActiveRecord::Base
  belongs_to :project
  has_many :participants, :through => :collaborations, :source => :user

活动参与者可能包括尚未接受的团队成员。所以,我想要这两个关联的交集。我的目标是做 1 次查询,而不是重复关联的 sql,并采摘一列。我发现这里描述的 Intersect http://www.rubydoc.info/github/rails/arel/Arel/SelectManager#intersect-instance_method 并试图从 https://github.com/rails/arel/commit/74caeaad157e79853b9c6804f561d3c70eea2346 推断它的用法。但我没有运气。

到目前为止,我所做的最好的事情是:

a = Activity.find(1)
team = a.project.participants.select('user_id').to_sql
peeps = a.participants.where("user_id in (#{team})")
peeps.pluck('thecolumn')

这会进行一次查询(好),不会重复关联的逻辑(好),并且不会加载所有 AR 对象,因为我只是在一个值之后(好)。但是,我希望能够:

a = Activity.find(1)
peeps = a.project.particpants.intersect a.project.participants

这可行,但返回一个 Arel::Nodes::Intersect...不知道如何从中获取结果。

【问题讨论】:

标签: ruby-on-rails-3.2 arel


【解决方案1】:

由于 Arel 支持 to_sql 你可以这样做:

a = Activity.find(1)
peeps = a.project.particpants.intersect a.project.participants #(sic)
Participant.find_by_sql(["SELECT participants.* FROM #{peeps.to_sql}", ...])

但我认为您的意思不是与自身相交,而是:

a = Activity.find(1)
peeps = a.particpants.intersect a.project.participants
Participant.find_by_sql(["SELECT * FROM #{peeps.to_sql}", ...])

您需要为查询提供参数。

我也成功地做这样的事情来获得关系

PublicActivity::Activity.from("(#{activities.to_sql} UNION #{task_activities.to_sql}) as activities").order("created_at DESC")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多