数据结构如下:
class Job
has_many job_sections
has_many job_products, through job_sections
end
class JobSection
belongs_to job
has_many job_products
end
class JobProduct
belongs_to product
belongs_to job_section
end
当我打电话给job.job_products时,我最终可能会遇到这样的事情:
#<JobProduct:0x007ff4128b0ca0
id: 18133,
product_id: 250,
quantity: 3,
frozen_cache: {},
discount: 0.0,
#<JobProduct:0x007ff4128b00c0
id: 18134,
product_id: 250,
quantity: 1,
frozen_cache: {},
discount: 0.0]
正如您所看到的,product_id在两个实例中都是相同的。 如何按产品ID合并数组的内容,以便检索并作为聚合值对其进行操作?
在某种程度上,我需要能够通过product_id
而不是id
对作业产品采取行动。
有效的结果是这样......
[#<SomeFancySeerviceObjectMaybe?
product_id: 250,
quantity: 4,
frozen_cache: {},
discount: 0.0]
我是否选择了一个简单的旧Ruby对象来处理它们,或者我是否必须重新考虑它的架构,或者是否(希望!)有一些Rails秘密酱可以帮助我吗? / p>
* FYI Job Section是该架构的最新成员,我不认为它经过特别深思熟虑。但是,我不能花太多时间来扭转现有的情况。 这个设置并不理想,我可能是多年来开始挑选它的第六个开发者。
非常欢迎您的建议。谢谢
答案 0 :(得分:1)
在SQL中,这将是这样的:
SELECT SUM(quantity)
FROM job_products
WHERE product_id = 250
GROUP BY product_id
您也可以在ActiveRecord中执行此操作。如果您只想要一个整数,可以使用pluck
:
total_quantity = job.job_products.
group(:product_id).
pluck("SUM(job_products.quantity)").
first
如果需要,您还可以pluck
多个列(在Rails 4+中),这就是它返回数组的原因。因此,如果您想同时享受平均折扣,那就很容易了。
如果您更喜欢JobProduct
实例,也可以获得该实例,但在您的情况下,由于分组,很多属性将为nil
。但你可以说:
summary = job.job_products.
group(:product_id).
select("SUM(job_products.quantity) AS total_quantity").
first
您将获得一个只读JobProduct
,其中包含名为total_quantity
的额外属性。所以你可以做summary.total_quantity
。但由于分组,summary
会有nil
id
,discount
等。基本上它只会有与select
相匹配的属性。这有点奇怪,但有时候它会让你编写适用于&#34;真实&#34; JobProduct
和这些摘要版本。