最初,当我尝试根据项目的确切内容(Items
)和Order
的频率,我使用以下代码:
:name_id
这段代码很精细。
然而,现在,我正试图建立一个更广阔的直方图。我仍想在一段时间内捕获:name_id
的频率,但现在我希望将该时间限制为dates = ["May 27, 2016", "May 30, 2016"]
items = Item.joins(:order).where("orders.start >= ?", dates.first).where("orders.start <= ?", dates.last)
histogram = {}
items.pluck(:name_id).uniq.each do |name_id|
histogram[name_id] = items.where(name_id:name_id).count
end
开始和结束。但是,我遇到了麻烦,结合了查询后面的ActiveRecord关系。具体来说,如果我的查询如下:
:name_id
如何加入2个查询,以便下面的代码对查询对象起作用?
Order
我尝试过的事情:
items_a = Item.joins(:order).where("orders.start >= ?", dates.first).where("orders.start <= ?", dates.last)
items_b = Item.joins(:order).where("orders.end >= ?", dates.first).where("orders.end <= ?", dates.last)
,但当然这不起作用,因为它会将结果转换为数组,其中items.pluck(:name_id).each do |name_id|
histogram[name_id] = items.where(name_id:name_id).count
end
等方法不起作用:
+
pluck
,这就是所有SO答案似乎都说的......但它对我不起作用,因为正如文档所说,(items_a + items_b).pluck(:name_id)
=> error
计算出交叉点,所以我的结果是这样的:
merge
目前,我用以下的方式修补了这个问题,但这并不是很理想。谢谢你的帮助!
merge
答案 0 :(得分:1)
您可以将两个查询合并为一个:
items = Item.joins(:order).where(
"(orders.start >= ? AND orders.start <= ?) OR (orders.end >= ? AND orders.end <= ?)",
dates.first, dates.last, dates.first, dates.last
)
这可能更具可读性:
items = Item.joins(:order).where(
"(orders.start >= :first AND orders.start <= :last) OR (orders.end >= :first AND orders.end <= :last)",
{ first: dates.first, last: dates.last }
)
Rails 5将支持or
方法,可能会让这更好一些:
items_a = Item.joins(:order).where(
"orders.start >= :first AND orders.start <= :last",
{ first: dates.first, last: dates.last }
).or(
"orders.end >= :first AND orders.end <= :last",
{ first: dates.first, last: dates.last }
)
或者在这种情况下可能没有更好的
答案 1 :(得分:0)
也许这会更清洁一点:
date_range = "May 27, 2016".to_date.."May 30, 2016".to_date
items = Item.joins(:order).where('orders.start' => date_range).or('orders.end' => date_range)