我有这个数据模型
House has_many :floors
(attributes => name,size,city)
楼层has_many :rooms, belongs_to :house
(attributes => name,rooms_count)
会议室has_many :furnitures, belongs_to :floor
(属性=>名称,大小)
家具belongs_to :room
(属性=>名称,大小,颜色)
我希望以这种方式查询
House.where(city: 'Paris').joins(floors: {rooms: :furnitures}).pluck(name, floors.id, floors.name, rooms.name, furnitures.name)
这是我想要的SQL请求:
=> SELECT houses.name, floors.id, floors.name, rooms.id, rooms.name, furnitures.id, furnitures.name FROM "houses" INNER JOIN "floors" ON "floors"."company_id" = "houses"."id" INNER JOIN "rooms" ON "rooms"."building_id" = "floors"."id" INNER JOIN "furnitures" ON "furnitures"."floor_id" = "rooms"."id" WHERE "houses"."name" = $1 [["city", "Paris"]]
现在我在一大堆数组中得到了原始数据,我想这样排序,但我很困惑:
[
{
name: 'toto',
floors: [
{
id: '123',
name: 'tata'
rooms: [
{
name: 'titi',
furnitures: [
{
name: 'table'
},
{
name: 'chair'
}
]
}
]
}
]
}
]
我需要避免N + 1请求,只拒绝选择*。
pluck_to_hash
gem可能会有所帮助,但对多表查询不起作用。
谢谢你的帮助。
答案 0 :(得分:1)
正如你所说,你可以把你想要的结果作为一个带有pluck的数组
function reverseFunc(str) {
var a = "" , c;
var b = 0;
for(var i = str.length-1; i >=0; i--)
{
c = str.charAt(i);
if((str[i] != ' ' && str[i] != '\n' && str[i] != '\t') || b > 0)
{
a = c + a;
b++;
}
}
return a;
}
为了给他们一个哈希,我认为你需要手动进行分组。如下所示。
arrays = House.where(city: 'Paris').joins(floors: {rooms: :furnitures}).pluck('name', 'floors.id', 'floors.name', 'rooms.name', 'furnitures.name')
会得到类似
的东西arrays = [
['toto', 123, 'tata', 'titi', 'table'],
['toto', 123, 'tata', 'titi', 'chair'],
['bob', 124, 'sue', 'hall', 'table'],
['bob', 124, 'sue', 'foyer', 'table']
]
arrays.inject([]) do |results, row|
name, floor_id, floor_name, room_name, furniture_name = row
house = results.detect{|o| o[:name] == name} || {name: name, floors: []}
results |= [house]
floor = house[:floors].detect{|o| o[:id] == floor_id} || {id: floor_id, name: floor_name, rooms: []}
house[:floors] |= [floor]
room = floor[:rooms].detect{|o| o[:name] == room_name} || {name: room_name, furnitures: []}
floor[:rooms] |= [room]
furniture = room[:furnitures].detect{|o| o[:name] == furniture_name} || {name: furniture_name}
room[:furnitures] |= [furniture]
results
end
答案 1 :(得分:1)
为什么不使用deep_pluck来获取嵌套关联。
House.where(city: 'Paris').deep_pluck(
:name,
floors: [
:id,
:name,
rooms: [
:name,
furnitures: :name,
]
]
)