获取最新产品的价格以及搜索栏和订单下拉菜单 RAILS 4
Get most recent product's price combined with a search bar and order dropdown RAILS 4
我有一个带有搜索栏和订购选项的产品列表。
一个商品有很多价格因为我创建了一个叫"prices"的table有历史记录,最近的价格就是现在的价格
产品列表在产品型号索引中,代码如下:
def index
scope = Product
# Search bar keywords
if params[:search]
scope = scope.search(params[:search])
end
# Order by dropdown selected option
if params[:ordering] && ordering = ORDERS[params[:ordering].to_i]
scope = scope.order(ordering)
end
@products = Product.all.order('id DESC')
end
我尝试添加以下行,但此代码重复 table 中每个价格的产品:
@products = Product.all.joins(:prices).order('id DESC')
我想要这样的结果:
我不知道如何在 rails 中加入或包含。
更新 ----------------------
Schema.rb:
ActiveRecord::Schema.define(version: 20150803051215) do
create_table "prices", force: :cascade do |t|
t.integer "product_id", limit: 4
t.decimal "price", precision: 10
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "comment", limit: 255
end
create_table "products", force: :cascade do |t|
t.string "name", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "published"
end
end
实际上,@products.each do |product|
谢谢。
一个有用的方法是,除了您的 has_many :prices
关系之外,添加与您的产品模型的 has_one :current_price
关系,以便您可以轻松获取当前价格。将这种关系定义为一个范围有点棘手(在代码中很容易,但我们希望这是一个适当的 Rails 范围,原因我将在接下来揭示)。一种方法是这样的:
class Product < ActiveRecord::Base
has_many :prices
has_one :current_price, -> {
where('prices.id = (SELECT MAX(id) FROM prices p2 WHERE product_id = prices.product_id)')
}, class_name: 'Price'
end
然后,您可以利用 Rails' .includes
方法在您的控制器中查询时将该范围加入到您的产品中:
@products = Product.includes(:current_price).all
在您看来,这现在既简单又高效:
<% @products.each do |product| %>
<%= product.name %>, current price: <%= product.current_price.price %>
<% end %>
但是,current_price
关系的定义有点简陋。另一个更简单的选择,如果你没有每个产品的很多价格,仍然非常有效,那就是通过 .includes
加载所有价格并在 Ruby:
中找到最近的价格
@products = Product.includes(:prices).all
那么,在您看来:
<% @products.each do |product| %>
<%= product.name %>, current price: <%= product.prices.max_by(&:created_at) %>
<% end %>
这样也可以在同一视图中轻松显示最低历史价格、起始价格或有关产品过去价格的任何其他信息。
我有一个带有搜索栏和订购选项的产品列表。
一个商品有很多价格因为我创建了一个叫"prices"的table有历史记录,最近的价格就是现在的价格
产品列表在产品型号索引中,代码如下:
def index
scope = Product
# Search bar keywords
if params[:search]
scope = scope.search(params[:search])
end
# Order by dropdown selected option
if params[:ordering] && ordering = ORDERS[params[:ordering].to_i]
scope = scope.order(ordering)
end
@products = Product.all.order('id DESC')
end
我尝试添加以下行,但此代码重复 table 中每个价格的产品:
@products = Product.all.joins(:prices).order('id DESC')
我想要这样的结果:
我不知道如何在 rails 中加入或包含。
更新 ----------------------
Schema.rb:
ActiveRecord::Schema.define(version: 20150803051215) do
create_table "prices", force: :cascade do |t|
t.integer "product_id", limit: 4
t.decimal "price", precision: 10
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "comment", limit: 255
end
create_table "products", force: :cascade do |t|
t.string "name", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "published"
end
end
实际上,@products.each do |product|
谢谢。
一个有用的方法是,除了您的 has_many :prices
关系之外,添加与您的产品模型的 has_one :current_price
关系,以便您可以轻松获取当前价格。将这种关系定义为一个范围有点棘手(在代码中很容易,但我们希望这是一个适当的 Rails 范围,原因我将在接下来揭示)。一种方法是这样的:
class Product < ActiveRecord::Base
has_many :prices
has_one :current_price, -> {
where('prices.id = (SELECT MAX(id) FROM prices p2 WHERE product_id = prices.product_id)')
}, class_name: 'Price'
end
然后,您可以利用 Rails' .includes
方法在您的控制器中查询时将该范围加入到您的产品中:
@products = Product.includes(:current_price).all
在您看来,这现在既简单又高效:
<% @products.each do |product| %>
<%= product.name %>, current price: <%= product.current_price.price %>
<% end %>
但是,current_price
关系的定义有点简陋。另一个更简单的选择,如果你没有每个产品的很多价格,仍然非常有效,那就是通过 .includes
加载所有价格并在 Ruby:
@products = Product.includes(:prices).all
那么,在您看来:
<% @products.each do |product| %>
<%= product.name %>, current price: <%= product.prices.max_by(&:created_at) %>
<% end %>
这样也可以在同一视图中轻松显示最低历史价格、起始价格或有关产品过去价格的任何其他信息。