How do I write a UNION chain with ActiveRelation?

后端 未结 4 547
小蘑菇
小蘑菇 2021-02-05 13:23

I need to be able to chain an arbitrary number of sub-selects with UNION using ActiveRelation.

I\'m a little confused by the ARel implementation of this, si

4条回答
  •  名媛妹妹
    2021-02-05 13:45

    Because of the way the ARel visitor was generating the unions, I kept getting SQL errors while using Arel::Nodes::Union. Looks like old-fashioned string interpolation was the only way to get this working.

    I have a Shift model, and I want to get a collection of shifts for a given date range, limited to five shifts per day. This is a class method on the Shift model:

    def 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|
    
        select{id}.
        where{|s| s.scheduled_start >= day}.
        where{|s| s.scheduled_start < day.tomorrow}.
        limit(options[:per_day])
    
      end.map{|q| "( #{ q.to_sql } )" }
    
      where %{"shifts"."id" in ( #{queries.join(' UNION ')} )}
    end
    

    (I am using Squeel in addition to ActiveRecord)

    Having to resort to string-interpolation is annoying, but at least the user-provided parameters are being sanitized correctly. I would of course appreciate suggestions to make this cleaner.

提交回复
热议问题