ruby-on-rails - 如果存在,如何用第二个表中的列值覆盖表列值?
问题描述
我正在构建电子商务应用程序,您可以在其中为产品设置用户特定的价格。如果没有为特定用户设置特定产品的价格,它将显示默认产品价格。
它工作正常,但我正在寻找更有效的解决方案,因为我对当前的解决方案不满意。
表:
- 用户
- 产品(所有产品信息 + 常规价格)
- 价格(user_id、product_id、user_price)
楷模:
class User < ApplicationRecord
has_many :prices
end
class Product < ApplicationRecord
has_many :prices
validates :name, presence: true
def self.with_user_prices(current_user)
Product.joins(
Product.sanitize_sql_array(['LEFT OUTER JOIN prices ON prices.user_id = ?
AND products.id = prices.product_id', current_user])
).select('products.*, prices.user_price')
end
end
class Price < ApplicationRecord
belongs_to :product
belongs_to :user
end
我如何在控制器中获得具有用户特定价格的所有产品:
@products = Product.with_user_prices(current_user)
我如何在视图中显示它们:
<% @products.each do |product| %>
<%= product.user_price ? product.user_price : product.regular_price %>
<% end %>
如您所见,我目前正在加入价格表,然后在视图中显示 user_price(价格表)(如果存在),否则显示常规价格(产品表)。
我很想在一个查询中解决所有问题,根据 current_user 只保留一个具有适当值的价格列
解决方案
您可以使用SQL COALESCE函数:
class Product < ApplicationRecord
# ...
def self.with_user_prices(user)
includes(:prices).where(prices: { user_id: user.id }).select(
'products.*, COALESCE(prices.user_price, products.regular_price) as price'
)
end
end
然后您可以通过以下方式简单地使用它:
<%= product.price %>
请注意,我Product.with_user_prices
通过使用 稍微简化了方法includes
,这将生成 SQLLEFT JOIN
查询,因为有条件 on prices
。
推荐阅读
- javascript - Onclick 事件处理程序给出一个值 [JS]
- python - 如何在不刷新页面python烧瓶的情况下自动更新数据?
- deployment - 如何优化 Tableau 仪表板的部署策略?
- reporting-services - SSRS 和顽固的 Excel 序列号
- html - powerapp 添加不断变化的超链接
- wordpress - 我无法在实时服务器上上传我的本地主机网站。它没有显示背景图像
- c# - Entity Framework Core:读取和删除数据之间的事务
- apache-spark - Spark-kafka:从 Spark 写入流时出现 org.apache.kafka.common.errors.TimeoutException
- angular - 限制刷新页面|浏览器限制| 角 6 |
- javascript - 函数内的变量范围