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

Sql 如何使复杂的命名范围与关联和其他命名范围配合使用[rails],sql,mysql,ruby-on-rails,activerecord,named-scope,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,

我在上有以下命名作用域

  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

您应该检查应用程序的日志文件,并查看Rails做出了哪些导致生成的查询失败的假设。如果您无法修复它,请向我们展示一个您试图通过其进行访问的示例关联,Rails将从日志文件生成查询


我的直觉是,Rails假设它可以访问表
可出租的\u项
,就像访问
可出租的\u项
,但是在这种情况下,您将其别名为
ri

Rails假设它可以访问表可出租的\u项。我已经尝试更改命名范围的select和from部分,以满足此要求。但当我这么做的时候,mysql抱怨“模棱两可的字段”。例如,我正在访问account.rentable\u items.available\u at。。。或集装箱物品。可出租物品。可在……购买。我可能有点搞错了。看起来您包装了整个子查询,并用
将其别名为t
。你能试着把它改成可租物品吗?如果这仍然不起作用,您可以编辑问题并将您在日志文件中看到的SQL粘贴到日志文件中吗?我不确定是什么原因导致double
WHERE
-子句,但我看到即使在简单的关联上也会发生这种情况。因此,这可能没什么可担心的。(但如果有人能解释一下,那还是很好的。)
  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))