如何使复杂的命名范围与关联和其他命名范围相匹配[rails]

时间:2010-02-07 20:14:11

标签: sql mysql ruby-on-rails activerecord named-scope

我在

上有以下命名范围
  class RentableItem < ActiveRecord::Base
  named_scope :available_at, lambda{ |starts_at, ends_at| { 
      :select => "t.*",
      :from => "(SELECT ri.*, COALESCE(c1.start_date, '#{starts_at}') AS EarliestAvailable,
                              COALESCE(c2.end_date, '#{ends_at}') AS LatestAvailable
                FROM rentable_items ri
                LEFT OUTER JOIN contracts c1 ON (ri.id = c1.rentable_item_id AND c1.start_date BETWEEN '#{starts_at}' AND '#{ends_at}')
                LEFT OUTER JOIN contracts c2 ON (ri.id = c2.rentable_item_id AND c2.end_date BETWEEN '#{starts_at}'
                AND '#{ends_at}' AND c2.start_date >= c1.end_date))
                AS t",
      :joins =>"LEFT OUTER JOIN contracts x ON (t.id = x.rentable_item_id AND x.start_date < t.LatestAvailable
                AND x.end_date > t.EarliestAvailable)",
      :conditions => "x.id IS NULL AND DATEDIFF(t.LatestAvailable, t.EarliestAvailable) >= #{(starts_at.to_date..ends_at.to_date).to_a.size - 1}"
      }}
end

这个named_scope上的单个调用就像一个魅力,但是当我试图将几个命名范围链接在一起,或者通过一个关联范围访问这个named_scope时,它会爆炸。我认为,select语句和custom from子句是问题所在。也许有人知道如何重写这个named_scope以允许通过关联进行链接和范围界定?

编辑:

感谢Shtééf,它正在努力工作。

  named_scope :available_at, lambda{ |starts_at, ends_at| { 
      :select => "rentable_items.*",
      :from => "(SELECT ri.*, COALESCE(c1.start_date, '#{starts_at}') AS EarliestAvailable,
                              COALESCE(c2.end_date, '#{ends_at}') AS LatestAvailable
                FROM rentable_items ri
                LEFT OUTER JOIN contracts c1 ON (ri.id = c1.rentable_item_id AND c1.start_date BETWEEN '#{starts_at}' AND '#{ends_at}')
                LEFT OUTER JOIN contracts c2 ON (ri.id = c2.rentable_item_id AND c2.end_date BETWEEN '#{starts_at}'
 AND '#{ends_at}' AND c2.start_date >= c1.end_date))
 AS rentable_items",
      :joins =>"LEFT OUTER JOIN contracts x ON (rentable_items.id = x.rentable_item_id AND x.start_date < rentable_items.LatestAvailable
AND x.end_date > rentable_items.EarliestAvailable)",
      :conditions => "x.id IS NULL AND DATEDIFF(rentable_items.LatestAvailable, rentable_items.EarliestAvailable) >= #{(starts_at.to_date..ends_at.to_date).to_a.size - 1}"
      }}

这允许我现在链接范围并通过关联访问它。

可能只有一个整容,一个小问题,其中一个条件加倍,导轨产生(在开始和结束时:

WHERE (`rentable_items`.container_item_id = 1) AND (((size > 10) AND (x.id IS NULL AND DATEDIFF(rentable_items.LatestAvailable, rentable_items.EarliestAvailable) >= 28)) AND (`rentable_items`.container_item_id = 1)) 

1 个答案:

答案 0 :(得分:0)

您应该检查应用程序的日志文件,并查看Rails正在做出的导致生成的查询失败的假设。如果您无法修复它,请向我们展示您尝试访问它的示例关联,并从日志文件生成查询Rails。

我的直觉是,Rails假设它可以仅rentable_items访问表rentable_items,而是在这种情况下将其别名为ri