Cocoon gem,collection_select不能和drink_id一起工作

时间:2017-12-27 01:06:18

标签: ruby-on-rails cocoon-gem

我使用Cocoon gem的结构,在我的app / views / order / _form.html.erb下面的代码工作正常:

<%= f.collection_select(:drink_id, @drinks, :id, :name, :prompt => "Select a drink") %>

但是当我在_drink_fields.html.erb中使用时,请不要这样做:

  

未定义的方法`drink_id&#39; #Drink:0x007fd30f9799f8

应用程序/视图/命令/ _drink_fields.html.erb

  <div class='nested-fields'>
<div class="field">
  <%= f.collection_select(:drink_id, @drinks, :id, :name, prompt: 'Select a drink') %>
</div>
<%= link_to_remove_association "remove", f %>
</div>

应用程序/视图/命令/ _form.html.erb

  <hr>
  <h3>Drinks</h3>
  <div id='drinks'>
    <%= f.fields_for :drinks do |drink| %>
      <%= render 'drink_fields', :f => drink %>
    <% end %>
    <div class='links'>
      <%= link_to_add_association 'add', f, :drinks %>
    </div>
  </div>
  <hr>

应用程序/视图/模型/ order.rb

class Order < ApplicationRecord
  belongs_to :drink, optional: true
  has_many :drinks
  accepts_nested_attributes_for :drinks, allow_destroy: true
end

应用程序/控制器/ orders_controller.rb

def set_order
  @order = Order.find(params[:id])
end

def set_drink
  @drinks = Drink.all
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
  params.require(:order).permit(:number, :drink_id, drinks_attributes: [:id, :name, :_destroy])
end

为什么我收到了它? 如何做好工作?

谢谢你们!

3 个答案:

答案 0 :(得分:2)

在检查您的关联时,我认为您在那里犯了一个错误。我看到以下

  • 订单属于饮料
  • 订单有很多饮料
  • 接下来是:饮料属于订单。所以喝一杯只能订购一次吗?

我的猜测是你错过了订单和饮料之间的联系表。所以添加一个简单的

class OrderedDrink < ActiveRecord::Base
  belongs_to :order
  belongs_to :drink 
end

您还需要该表,因此您必须添加迁移(显然)。 (你可以在那里收到一些金额:例如他们订购了5个可乐)。

然后在Order中获得

 class Order
   has_many :ordered_drinks, inverse_of: :order 
   has_many :drinks, through: :ordered_drinks

   accepts_nested_attributes_for :ordered_drinks 
 end 

Drink编写

 class Drink 
   has_many :ordered_drinks
   has_many :orders, through: :ordered_drinks 
 end 

(你可能不需要这些关系,知道饮料的订单数量是多少)

然后编辑drinks而不是编辑/管理ordered_drinks关联,而您的部分/集合选择将按预期运行。

答案 1 :(得分:1)

它不起作用的原因是因为@drinks对象上没有SUM方法(应与数据库中的drink_id列对应)。您可能希望使用drink_id代替:id

答案 2 :(得分:1)

谢谢大家帮助解决这个问题,尤其是@nathanvda。 我的错误是忘了加入饮料和订单的桌子,所以我重新创建了项目,除了那个饮料和订单表,我创建了一个像@nathanvda回答的有序饮用表。

应用程序/模型/ order.rb

has_many :ordered_drinks, inverse_of: :order 
has_many :feeds, through: :ordered_drinks

accepts_nested_attributes_for :ordered_drinks, allow_destroy: true

应用程序/控制器/ orders_controller.rb

before_action :set_drink, only: [:new, :edit, :update, :destroy]
  def set_drink
    @drinks = Drink.all
  end
def order_params
  params.require(:order).permit(:number, ordered_drinks_attributes: [:id, :order_id, :drink_id, :_destroy, drinks_attributes: [:id, :name, :_destroy]])
end

应用程序/视图/命令/ _form.html.erb

<hr>
<h3>Drinks</h3>
<div id='ordered_drinks'>
  <%= f.fields_for :ordered_drinks do |ordered_drink| %>
    <%= render 'ordered_drink_fields', :f => ordered_drink %>
  <% end %>
  <div class='links'>
    <%= link_to_add_association 'add drink', f, :ordered_drinks %>
  </div>
</div>
<hr>

应用程序/视图/命令/ _ordered_drink_fields.html.erb

<div class='nested-fields'>
  <div class="field">
    <%= f.collection_select(:drink_id, @drinks, :id, :name, include_blank: false) %>
  </div>
  <%= link_to_remove_association "remove drink", f %>
</div>

如果有人遇到同样的问题,请与我联系或发送消息。