有人可以指出ActiveRecord是如何从Left Outer Join查询中生成嵌套哈希的吗?
我正在为复杂查询做一个急切的加载,其中需要将不同的WHERE子句应用于has_many关联表。当Rails生成查询以获取应用条件的关联时,我没有得到预期的结果。
我能够将结果构建成片段 - 用于驱动表,并单独用于has_many关联。现在我需要将关联表的结果合并到驱动表中。
或者简单来说,我在应用程序中有以下表格。
Items
___________________
| id | item_name |
___________________
| 1 | "Item One" |
| 1 | "Item One" |
| 1 | "Item One" |
| 1 | "Item One" |
| 1 | "Item One" |
___________________
Inventories
_________________
| id | quantity |
_________________
| 1 | 10 |
| 1 | 10 |
| 1 | 10 |
| 1 | 10 |
| 1 | 10 |
_________________
Transactions
_________________________________________
| id | item_id | tran_status | tran_qty |
_________________________________________
| 1 | 1 | "ordered" | 1 |
| 2 | 1 | "picked" | 1 |
| 3 | 1 | "ordered" | 4 |
| 4 | 1 | "canceled" | 5 |
| 5 | 1 | "ordered | 2 |
_________________________________________
Adjustments
_______________________________________
| id | item_id | adj_status | adj_qty |
_______________________________________
| 1 | 1 | "adjusted" | 1 |
| 4 | 1 | "canceled" | 1 |
_______________________________________
我正在尝试使用以下格式为AJAX操作创建JSON响应(使用JBuilder)。
[{"id": 1,
"name": "Item One",
"inventory": {"quantity": 10},
"transactions": [ {"tran_status": "Ordered", "tran_qty": 1},
{"tran_status": "Picked", "tran_qty": 1},
{"tran_status": "Ordered", "tran_qty": 4},
{"tran_status": "Ordered", "tran_qty": 2} ],
"adjustments": [ {"adj_status": "Adjusted", "adj_qty": 1} ]
}
]
既然可能会为多个项目请求这个,我想在查询期间做一个急切的负载。
但是,以下查询不起作用。 Rails生成左外连接查询并破坏该方。
Item.includes(:inventory).
includes(:transactions).
where("transactions.status not in ('canceled')").
references(:transactions).
includes(:adjustments).
where("adjustments.status not in ('canceled')").
references(:adjustments).
where(id: params[:item])
所以,我尝试做的是分三步执行查询,最后在JBuilder中迭代创建一个哈希或Openstruct。
items = Item.includes(:inventory).
item_ids = items.collect(&:id)
trans = Transaction.where(item_id: item_ids).where("status not in ('canceled')")
adjs = Adjustment.where(item_id: item_ids).where("status not in ('canceled')")
现在我想将所有这些合并为一个哈希数组。
我意识到Rails会在内部做这样的事情,并考虑利用现有的知识,而不是用我有限的知识构建一种效率较低的方法。
任何帮助都将不胜感激。
问题在于尝试自己构建解决方案。核心问题是让Rails生成具有应用于关联表的条件的查询。接受的答案是建立与条件的关联的建议(可以在接受的答案的讨论主题中找到)。
答案 0 :(得分:1)
如果我找对你,你需要迭代项目:
items = Item.includes(:inventory)
result = []
items.each do |i|
result << {
:item => i,
:trans => Transaction.where(item_id: i.id ).where("status not in ('canceled')"),
:adjs => Adjustment.where(item_id: i.id).where("status not in ('canceled')")
}
end
或者您可以使用单个集合在数组中获取它:
result = Item.includes(:inventory, :transactions, :adjustments).collect { |i| i,
i.transactions.where("status not in ('canceled')"),
i.adjustments.where("status not in ('canceled')")
}
,前提是您已正确设置关联
答案 1 :(得分:0)
require 'json'
hash_arr = []
Item.includes(:inventories,:transactions,:adjustments).all.each do |item|
hash = {"id"=>item.id,
"name"=>item.name,
"inventory"=>item.inventories.count,
"transactions"=>item.transactions.select("tran_status,tran_qty").collect{ |x|
{:tran_status=>x.tran_status,:tran_qty=>x.tran_qty}
},
"adjustments"=>item.adjustments.select("adj_status,adj_qty").collect{|x| {:adj_status=>x.adj_status,:adj_qty=>x.adj_qty}
}
}
hash_arr.push hash
end
hash_arr.to_json
希望这符合您的要求
或者您可以使用as_json
并指定自己的JSON格式(这会更清晰)。查看here