在计数中包含嵌套关联属性



我有这样的类:

class Orders < ActiveRecord::Base
has_many :items
has_many :types, through: :items
accepts_nested_attributes_for :items
end
class Item < ActiveRecord::Base
belongs_to :type
belongs_to :order
end
class Type < ActiveRecord::Base
has_many :items
end

订单上有几个项目,以下是概述以及项目和类型:

<Item:0x00007fbcb185c170
id: 1,
finish: "Fir",
size: "38",
type_id: 8,
order_id: 1>
<Type:0x00007fbcace363e8
id: 8,
type: "Door",
name: "Jeldwen Premium Interior">

商品可能具有相同的类型,但饰面和尺寸属性不同。我需要从数据库中获取一个订单并以人类可读的格式呈现它们,如下所示:

Order: {
Types: 
{
Name: "Jeldwen Premium Interior",
Type: "Door",
Items: 
{
finish: "fir",
size: "36", 
quanity: "8" # sum of items in the database with same `finish` and `size`
}, 
{
finish: "fir",
size: "58", 
quanity: "8" # sum of items in the database with same `finish` and `size`   
}
}       

我希望能够通过一个数据库调用获得所有这些信息,并且我在那里得到了一部分,我只是缺少类型名称-

`Order.where(id: 1).joins(:items).joins(:type).group("items.type_id", "items.size", "items.color").count`

返回type_id、大小、完成度和数量:

{[3, "36", "fir"]=>40,
[3, "48", "fir"]=>36,
[3, "36", "oak"]=>90,
[4, "48", "oak"]=>18}

我想返回type.nametype.name伯爵,这可能吗?因此,一行将如下所示:

["Jeldwen Premium Interior", "door", 3, "36", "fir"]=>40

我昨天遇到了这个问题,最终使用了find_by_sql

您可以在sql console或以下站点测试 SQL

您的轨道查询

.joins(:items).joins(:type).group("items.type_id", "items.size", "items.color").count

可以用 SQL 完成

SELECT items.type_id, items.size, items.color, types.name, COUNT(types.id) AS NumberOfTypes, COUNT(types.name) AS NumberOfNames FROM items INNER JOIN types on items.id = types.item_id GROUP BY items.type_id, items.size, items.color;

在作用域中

class Item
scope :items_count, -> { find_by_sql("SELECT items.type_id, items.size, items.color, types.name, COUNT(types.id) AS NumberOfTypes, COUNT(types.name) AS NumberOfNames FROM items INNER JOIN types on items.id = types.item_id GROUP BY items.type_id, items.size, items.color;") }
end

你可以打电话

items = Order.first.items_count

它将返回一个项目数组,不带count,也不带types。像这样:

=> [#<Item:0x00564d6bf08c28 id: nil, type: "type1test", size: 133, color: 'blue'>,
#<Item:0x00564d6bef7108 id: nil, type: "type1test", size: 136, color: 'blue'>,
#<Item:0x00564d6bef6e88 id: nil, type: "type1test", size: 137, color: 'blue'>,
#<Item:0x00564d6bef6cf8 id: nil, type: "type1test", size: 132, color: 'blue'>,
#<Item:0x00564d6bef6af0 id: nil, type: "type1test", size: 141, color: 'blue'>,
#<Item:0x00564d6bef68c0 id: nil, type: "type1test", size: 135, color: 'blue'>]

items数组将不具有类型,但它将包含一个numberofitems的列,其结果为COUNT

items[0].numberoftypes 
=> 6
items[0].numberofnames 
=> 4

无论如何,这是行不通的,因为您不能在不同的表中GROUP BY不同的字段并同时拥有 2 个COUNT

您可以尝试使用 sql 在此控制台中对其进行测试,并发现这是不可能的。

它不会为您的一列返回正确的计数数,但这种技术比您现在使用的技术更好,因为您不需要执行2 JOINS并且它将返回对象。

SQL非常简单,您可以参考 https://www.w3schools.com/sql/以更好地理解 http://guides.rubyonrails.org/active_record_querying.html 中包含的任何sql

最新更新