Rails 5:从联接表中显示表单 [英] Rails 5: Displaying form from Joined table

查看:105
本文介绍了Rails 5:从联接表中显示表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是直接的关注直到之前的问题,我在其中构建了适当的相关内容表/模型。但是为了澄清起见,我将在这里重新定义布局...



我的模型:



顺序.rb

 类订单< ApplicationRecord 
属于:user
has_many:quantities
has_many:meals,通过::quantities
end

meal.rb

  Class Meal< ApplicationRecord 
has_many:数量
has_many:orders,通过::quantities
end

quantity.rb

 类数量< $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

user.rb

 类用户< ApplicationRecord 
#包括默认的devise模块。其他可用的有:
#:可确认的::可锁定的:超时的:可跟踪的以及omniauthable的
devise:database_authenticatable,可注册的,
:可恢复的,可记住的,可验证的

has_many:orders
after_create:add_order

def add_order
self.create_order
end

因此,每个用户有1个订单,他们可以在其订单上更新每餐的数量。我需要将所有这些都显示在主页(我已经做过一个家庭控制器)上,对此进行了迭代,以供我参考:

  order.quantities.each做|记录| 
record.meal.name#表示关联餐的名称
record.quantity#表示用餐量
结束

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



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



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



如果有人可以请尝试解释什么概念使我难以理解,以便我可以更好地理解多对多关系,我觉得这似乎可以澄清我显然也有很多与Ruby相关的困惑。

解决方案

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

 <%user.orders.each | order | %> 
< div class = order>
< p>以<%= 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 
属于:user
has_many:quantities
has_many:meals,通过::quantities
accepts_nested_attributes_for:quantities
end

这使您可以在与订单一起创建嵌套数量:

  Order.create(quantities_attributes:[{餐ID:1,数量:2},{餐ID:3,数量:1}])

您将像这样设置嵌套表单:

 <%= form_with( @order)做| f | %> 
<%= fields_for:数量| 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:数量%>
<%= qf.number_field:数量%>
< / div>
< / div>
<%end%>
< div class = actions>
<%= f.submit%>
< / div>
<%end%>

和控制器:

 类OrdersController< ApplicationController 

before_action:set_order,仅:[:show,:edit,:update,:destroy]

def new
@order = Order.new
#以此形式为字段填充数量
10.times {@ order.quantities.new}
结束

def创建
#你有一个current_user方法
@order = current_user.orders.new(order_params)
如果@ order.save
redirect_to'somewhere'
else
render:new
结束
结束

def更新
#如果@ order.update(order_params)
redirect_to,我假设您有current_user方法
'某处'
其他
渲染:new
end
end

private
def set_order
@order = Order.find (params [:order_id])
结束

def order_params
params.require(:order).permit(:foo,:bar,数量属性:[:meal_id,:quantity ])
结束
结束


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.

解决方案

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

这篇关于Rails 5:从联接表中显示表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆