Rails 5 has_many_through在结果中包含数据透视表

时间:2019-01-23 16:36:44

标签: ruby-on-rails activerecord ruby-on-rails-5

我有一个带有餐厅和产品的Rails 5应用程序。一种产品有很多餐厅,而另一种餐厅则有很多产品。我创建了一个数据透视表并创建了has_many_through关系,因为我想使用该数据透视表。

产品:

has_many :restaurant_products, dependent: :destroy
has_many :restaurants, through: :restaurant_products

餐厅:

has_many :restaurant_products, dependent: :destroy
has_many :products, through: :restaurant_products

由于每个餐厅都可以修改每种产品的价格,因此我在restaurant_products表中添加了custom_price列。

现在我可以在某个餐厅获得所有产品:

@restaurant.products

但是这样,当我列出产品时,我无法获得自定义价格。如何以某种方式包含或访问正确的数据记录以获取自定义价格?

3 个答案:

答案 0 :(得分:0)

您可以使用以下内容:

@restaurant.restaurant_products.joins(:products).select('restaurant_products.custom_price, products.*')

这将使您可以访问实例,包括产品的所有列以及联接表的自定义价格。

生成的SQL类似于:

SELECT restaurant_products.custom_price, products.* 
FROM `restaurant_products` 
INNER JOIN `products` ON `products`.`id` = `restaurant_products`.`product_id` 
WHERE `restaurant_products`.`restaurant_id` = 1

快速提示:返回的内容可能看起来有些奇怪,例如:

[#<RestaurantProduct id: 1, custom_price: 10>]

...尽管,如果您在此处调用attributes或实例上的product属性,则可以访问所需的所有内容。


尽管您需要访问产品本身上的方法,但上面的内容可以快速有效地访问记录的数据,

@product_details = @restaurant.restaurant_products.includes(:products)

然后遍历数据:

@product_details.each do |product_detail|
  product_detail.custom_price

  product_detail.product.column_data
  product_detail.product.a_method
end

希望这些帮助-让我知道您的生活状况或有任何疑问。

答案 1 :(得分:0)

只需提供一个自定义选择,其中包括联接表中的行:

@products = @restaurant.products
           .select('products.*, restaurant_products.custom_price')

这将返回restaurant_products.custom_price,就像它在products上的列中一样。如果您想使用别名而不是AS,则可以custom_price提供别名。

因此您可以这样做:

<table>
  # ...
  <% @products.each do |product| %>
  <tr>
    <td><%= product.name %></td>
    <td><%= product.custom_price %></td>
  </tr>
  <% end %>
</table>

答案 2 :(得分:0)

在这种情况下,始终最好在枢轴表上进行查询

@restaurant_products = RestaurantProduct.includes(:product)
                                        .where(restaurant_id: @restaurant.id)

您可以简单地在视图中显示它,如下所示。

<table>
  <% @restaurant_products.each do |resta_product| %>
  <tr>
    <td><%= resta_product.product.name %></td>
    <td><%= resta_product.custom_price %></td>
  </tr>
  <% end %>
</table>

您甚至可以委托所有产品方法直接在restaurant_product上使用。