Rails 5: отображение формы из объединенной таблицы - PullRequest
0 голосов
/ 27 октября 2018

Это мой первый набег в объединенные таблицы и отношения «многие ко многим», и я также относительно новичок в Ruby / Rails.

Это прямое продолжение предыдущего вопроса , где я построил соответствующие связанные таблицы / модели.Но для ясности я переопределю макет здесь ...

Мои модели:

order.rb

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

food.rb

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

amount.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

Но проблема, с которой я сейчас сталкиваюсь, связана с включением этого соединенияв домашний контроллер, чтобы страница могла отображать информацию.

В отношениях 1-к-1 я недооцениваю, как перенести информацию о соответствующем пользователе на страницу, но в этом «многие ко многим»отношения, логика теряется на мне, так как каждый раз, когда я вношу информацию на контроллере, я получаю неопределенную переменную.

Я даже не хочу показывать свою попытку, потому что я думаю, что концепция этого типаотношения потеряны на мне.(Метод цепочки, использованный в примере итерации, имеет смысл для меня, если посмотреть на него, но тогда как с этим справиться в контроллере, а не подсказка)

Если кто-то может попытаться объяснить, какая концепция ускользает от менятак что я могу лучше понять отношения «многие ко многим», я чувствую, что это могло бы прояснить большую путаницу, связанную с Ruby, которая у меня, по-видимому, тоже.

1 Ответ

0 голосов
/ 27 октября 2018

Чтобы отобразить каждый заказ и количество для каждого, все, что вам нужно сделать, это просто вложенная итерация:

<% 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
...