问题
This is my first foray into joined tables and Many-to-Many relationships and I am relatively new to Ruby/Rails as well.
This is a direct follow up to a previous question where I built out the appropriate related tables/Models. But for sake of clarify, I'll redefine the layout here...
My 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
So each user has 1 order, and they can update the quantity of each meal on their order. I need to display all of this on a 'homepage'(I have made a home controller) of which I was given this iteration as reference:
order.quantities.each do |record|
record.meal.name # for name of associated meal
record.quantity # for quantity of meal
end
But the issue I am having now is incorporating this joined table into the home controller so that the page can actually display the information.
In 1-to-1 relationships, I understoop how to pull the related user's info onto the page, but in this Many-to-Many relationship, the logic is getting lost on me as anytime I bring in the information on the controller, I get an undefined variable.
I don't even want to show my attempt because I think a concept of this type of relationship is lost on me. (The method chaining used in the iteration example makes sense to me looking at it, but then how to deal with that in the controller, not a clue)
If someone could please try to explain what concept is eluding me so that I can understand Many-to-Many relationships better, I feel as though it might clarify a lot of Ruby related confusion I apparently have as well.
回答1:
To display each order and the quanties for each all you need to do is just a nested iteration:
<% 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 %>
You also have accepts_nested_attributes
on the wrong model. It should be:
class Order < ApplicationRecord
belongs_to :user
has_many :quantities
has_many :meals, through: :quantities
accepts_nested_attributes_for :quantities
end
This lets you create nested quantities when along with an order:
Order.create(quantities_attributes: [{ meal_id: 1, quantity: 2 }, { meal_id: 3, quantity: 1 }])
You would setup the nested form like so:
<%= 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 %>
And the controller:
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
来源:https://stackoverflow.com/questions/53023671/rails-5-displaying-form-from-joined-table