Ruby on rails 如何在where子句中使用实例方法
在我的Ruby on rails 如何在where子句中使用实例方法,ruby-on-rails,Ruby On Rails,在我的类别模型中,我有一个实例方法,可以将类别内所有产品的所有平均价格相加: def price_average(store_id) products.pluck(:price_average).map { |h| h[store_id] }.sum end 在我的类别控制器中,我试图使用过滤器仅显示平均价格高于特定金额的类别。我该怎么做 我这里的主要挑战是,price\u average不是一个列名,所以做一些类似于@categories的事情。其中(“price\u average('
类别
模型中,我有一个实例方法,可以将类别内所有产品的所有平均价格相加:
def price_average(store_id)
products.pluck(:price_average).map { |h| h[store_id] }.sum
end
在我的类别
控制器中,我试图使用过滤器仅显示平均价格高于特定金额的类别。我该怎么做
我这里的主要挑战是,price\u average
不是一个列名,所以做一些类似于@categories的事情。其中(“price\u average('1')>1000”)
就是失败了
模型的结构如下所示:
class Category < ApplicationRecord
# t.string "name"
# t.datetime "created_at", precision: 6, null: false
# t.datetime "updated_at", precision: 6, null: false
has_and_belongs_to_many :products
has_many :prices, through: :products
def price_average(store_id)
products.pluck(:price_average).map { |h| h[store_id] }.sum
end
end
class Product < ApplicationRecord
# t.string "name"
# t.datetime "created_at", precision: 6, null: false
# t.datetime "updated_at", precision: 6, null: false
# t.jsonb "price_average", default: {}
has_and_belongs_to_many :categories
has_many :prices
end
类别
在price\u average
列中,我存储的是json,其中store\u id是用于检索值的索引。您可以在类别表中添加一个名为price\u average的列,并在每次添加类别中的产品或从类别中删除产品时更新它,然后您就可以依赖此字段
请注意,当您需要在运行时显示的平均值大于您计算的值时,这将节省处理时间,正如问题所理解的,使用SQL查询提出解决方案,以优化解决方案,而不更改模式
第1步:
获取store\u id为store\u id的所有产品的平均价格
# GET price_average of products, grouped on product and category.
# This query would be a sub query to the next step.
# SQL code
SELECT
id, category_id,
(json_array_elements(products.price_average)->>'STORE_ID')::numeric as price_average
FROM products
GROUP BY id, category_id
第二步:
查找价格平均值之和,并过滤总和大于最小价格平均值变量的产品和类别
# SQL code
SELECT products.id, products.category_id, sum(products.price_average) as price_average
FROM (
# Query from step 1
SELECT id, category_id, (json_array_elements(products.price_average)->>'STORE_ID')::numeric as price_average
FROM products
GROUP BY id, category_id
) AS products
GROUP BY products.id, products.category_id
HAVING sum(products.price_average) > MIN_PRICE_AVERAGE_VARIABLE
第三步:
从步骤2中获取类别的ID,使用相同的ID查找所有类别。使用exec_query执行在上一步中获得的查询
# ruby code
@connection = ActiveRecord::Base.connection
result = @connection.exec_query("SELECT product_category.category_id FROM (
SELECT products.id, products.category_id AS category_id, sum(products.price_average) as price_average
FROM (
SELECT id, category_id, (json_array_elements(products.price_average)->>#{STORE_ID})::numeric as price_average
FROM products
GROUP BY id, category_id
) AS products
GROUP BY products.id, products.category_id
HAVING sum(products.price_average)>#{MIN_PRICE_AVERAGE_VARIABLE}
) AS product_category")
category_ids = result.rows.flatten.uniq
Category.where(id: category_ids)
话虽如此,这里有一个模式更改建议:
- 最好创建一个带有(产品标识、类别标识、商店标识、平均价格、其他公共列)的表
- 这将有助于找到一个总和(平均价格),根据产品标识、类别标识、商店标识的任意组合进行过滤或分组
让我知道这是否有帮助。谢谢能否添加类别、产品和门店之间的关联详细信息。平均价格是一个杂烩吗?门店标识的角色?price_average的列类型还是price_average又是一种实例方法?刚刚编辑了原始帖子。