gpt4 book ai didi

ruby-on-rails - 如何使用 ActiveRelation 编写 UNION 链?

转载 作者:行者123 更新时间:2023-12-03 02:11:15 24 4
gpt4 key购买 nike

我需要能够使用 ActiveRelation 将任意数量的子选择与 UNION 链接起来。

我对 ARel 的实现有点困惑,因为它似乎假设 UNION 是一个二进制运算。

但是:

( select_statement_a ) UNION ( select_statement_b ) UNION ( select_statement_c )

是有效的 SQL。这是否可以在不进行令人讨厌的字符串替换的情况下实现?

最佳答案

尽管亚当·拉塞克(Adam Lassek)走在正确的 rails 上,但你可以做得比他提出的更好一点。我刚刚解决了一个类似的问题,试图从社交网络模型中获取 friend 列表。可以通过各种方式自动获取好友,但我希望有一个 ActiveRelation 友好的查询方法来处理进一步的链接。所以我有

class User
has_many :events_as_owner, :class_name => "Event", :inverse_of => :owner, :foreign_key => :owner_id, :dependent => :destroy
has_many :events_as_guest, :through => :invitations, :source => :event

def friends


friends_as_guests = User.joins{events_as_guest}.where{events_as_guest.owner_id==my{id}}
friends_as_hosts = User.joins{events_as_owner}.joins{invitations}.where{invitations.user_id==my{id}}

User.where do
(id.in friends_as_guests.select{id}
) |
(id.in friends_as_hosts.select{id}
)
end
end

end

它利用了 Squeels 子查询支持。生成的SQL是

SELECT "users".* 
FROM "users"
WHERE (( "users"."id" IN (SELECT "users"."id"
FROM "users"
INNER JOIN "invitations"
ON "invitations"."user_id" = "users"."id"
INNER JOIN "events"
ON "events"."id" = "invitations"."event_id"
WHERE "events"."owner_id" = 87)
OR "users"."id" IN (SELECT "users"."id"
FROM "users"
INNER JOIN "events"
ON "events"."owner_id" = "users"."id"
INNER JOIN "invitations"
ON "invitations"."user_id" =
"users"."id"
WHERE "invitations"."user_id" = 87) ))

通过对上述代码稍加修改来演示需要可变数量组件的替代模式

  def friends


friends_as_guests = User.joins{events_as_guest}.where{events_as_guest.owner_id==my{id}}
friends_as_hosts = User.joins{events_as_owner}.joins{invitations}.where{invitations.user_id==my{id}}

components = [friends_as_guests, friends_as_hosts]

User.where do
components = components.map { |c| id.in c.select{id} }
components.inject do |s, i|
s | i
end
end


end

这是对OP确切问题的解决方案的粗略猜测

class Shift < ActiveRecord::Base
def self.limit_per_day(options = {})
options[:start] ||= Date.today
options[:stop] ||= Date.today.next_month
options[:per_day] ||= 5

queries = (options[:start]..options[:stop]).map do |day|

where{|s| s.scheduled_start >= day}.
where{|s| s.scheduled_start < day.tomorrow}.
limit(options[:per_day])

end

where do
queries.map { |c| id.in c.select{id} }.inject do |s, i|
s | i
end
end
end
end

关于ruby-on-rails - 如何使用 ActiveRelation 编写 UNION 链?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8045823/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com