Rails 5: 显示加入的表格 table

Rails 5: Displaying form from Joined table

这是我第一次尝试连接 table 和多对多关系,我对 Ruby/Rails 也比较陌生。

这是对之前 的直接跟进,我在其中构建了适当的相关 tables/Models。但是为了清楚起见,我将在这里重新定义布局...

我的模特:

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 个订单,他们可以更新订单上每餐的数量。我需要在 'homepage'(我制作了一个家庭控制器)上显示所有这些,我得到了这个迭代作为参考:

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

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

在一对一的关系中,我明白如何将相关用户的信息拉到页面上,但在这种多对多的关系中,每当我引入信息时,我就会迷失逻辑在控制器上,我得到一个未定义的变量。

我什至不想表现出我的尝试,因为我认为我已经忘记了这种关系的概念。 (迭代示例中使用的方法链接对我来说很有意义,但是如何在控制器中处理它,而不是线索)

如果有人可以尝试解释我不明白的概念,以便我能更好地理解多对多关系,我觉得它可能会澄清很多 Ruby 相关的困惑,我显然有还有。

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

<% user.orders.each do |order| %>
  <div class="order"> 
    <p>Ordered at <%= order.created_at %></p>
    <% order.quantites.each do |q| %>
    <div class="quantity"> 
       <%= q.meal.name >: <%= q.quantity %>
    </div>
    <% end %>
  </div>
<% 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| %>
  <div class="quantity">
    <div class="field">
      <%= qf.label :meal_id %>
      <%= qf.collection_select :meal_id, Meal.all, :id, :name %>
    </div>
    <div class="field">
      <%= qf.label :quantity %>
      <%= qf.number_field :quantity %>
    </div>
  </div>
  <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% 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