我有一个带有餐厅和产品的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
但是这样,当我列出产品时,我无法获得自定义价格。如何以某种方式包含或访问正确的数据记录以获取自定义价格?
答案 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
上使用。