获取最新产品的价格以及搜索栏和订单下拉菜单 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 %>

这样也可以在同一视图中轻松显示最低历史价格、起始价格或有关产品过去价格的任何其他信息。