Rails 5:从连接表中显示表单

这是我第一次涉及连接表和多对多关系,我对Ruby / Rails也相对较新。

这是对前一个问题的直接跟进,我在其中构建了相应的相关表格/模型。 但为了澄清,我将在这里重新定义布局……

我的模特:

order.rb

class Order < ApplicationRecord belongs_to :user has_many :quantities has_many :meals, through: :quantities end 

meal.rb

 class Meal < ApplicationRecord has_many :quantities has_many :orders, through: :quantities end 

quantity.rb

 class Quantity < ApplicationRecord belongs_to :order belongs_to :meal accepts_nested_attributes_for :quantities end 

user.rb

 class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_many :orders after_create :add_order def add_order self.create_order end 

因此每个用户有1个订单,他们可以更新订单上每餐的数量。 我需要在’主页’(我已经制作了一个家庭控制器)上显示所有这些,我给这个迭代作为参考:

 order.quantities.each do |record| record.meal.name # for name of associated meal record.quantity # for quantity of meal end 

但我现在遇到的问题是将这个连接表合并到家庭控制器中,以便页面可以实际显示信息。

在一对一的关系中,我不知道如何将相关用户的信息提取到页面上,但是在这种多对多关系中,随着我在控制器上引入信息时,逻辑就会迷失在我身上。得到一个未定义的变量。

我甚至不想展示我的尝试,因为我认为这种关系的概念在我身上失去了。 (迭代示例中使用的方法链接对我来说很有意义,但是后来如何在控制器中处理它,而不是线索)

如果有人可以请试着解释一下这个概念是什么,以便我能更好地理解多对多关系,我觉得它可能会澄清很多与Ruby相关的混乱,我显然也有。

要显示每个订单和每个订单的量,您只需要嵌套迭代:

 <% user.orders.each do |order| %> 

Ordered at <%= order.created_at %>

<% order.quantites.each do |q| %>
<%= q.meal.name >: <%= q.quantity %>
<% end %>
<% end %>

您还在错误的模型上有accepts_nested_attributes 。 它应该是:

 class Order < ApplicationRecord belongs_to :user has_many :quantities has_many :meals, through: :quantities accepts_nested_attributes_for :quantities end 

这使您可以在订单时创建嵌套数量:

 Order.create(quantities_attributes: [{ meal_id: 1, quantity: 2 }, { meal_id: 3, quantity: 1 }]) 

您可以像这样设置嵌套表单:

 <%= form_with(@order) do |f| %> <%= fields_for :quantities do |qf| %> 
<%= qf.label :meal_id %> <%= qf.collection_select :meal_id, Meal.all, :id, :name %>
<%= qf.label :quantity %> <%= qf.number_field :quantity %>
<% end %>
<%= f.submit %>
<% end %>

和控制器:

 class OrdersController < ApplicationController before_action :set_order, only: [:show, :edit, :update, :destroy] def new @order = Order.new # this seeds the form with fields for quantities 10.times { @order.quantities.new } end def create # I'm assuming you have a current_user method @order = current_user.orders.new(order_params) if @order.save redirect_to 'somewhere' else render :new end end def update # I'm assuming you have a current_user method if @order.update(order_params) redirect_to 'somewhere' else render :new end end private def set_order @order = Order.find(params[:order_id]) end def order_params params.require(:order).permit(:foo, :bar, quantities_attributes: [:meal_id, :quantity]) end end