嵌套字段和强参数 [英] Nested fields and strong parameters

查看:34
本文介绍了嵌套字段和强参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Rails 4 中遇到了一个复杂的问题,我将尝试在下面进行描述.我使用的是简单的表单和 awesome_nested_fields gems.

I am having a complex issue in Rails 4, which I will try to describe below. I am using simple form and awesome_nested_fields gems.

我的应用中有一堆事件,其中包含一些字段

I have a bunch of events with some fields in my app

这是我在实现 accepts_nested_attributes 之前的工作 event_controller 参数:

Here's my working event_controller params before the implementation of accepts_nested_attributes:

private

  def event_params
    params.require(:event).permit(:title, :description, :type_id, :price, :program,
                                  :start_date, :end_date, :image, category_ids: [])
  end

现在我想在我的活动中添加一些演讲者,并让用户决定每个活动需要多少演讲者.因此,根据他们的文档,我添加了嵌套字段 gem 并使扬声器成为嵌套字段.

Now I would like to add some speakers to my events, and make the user decide, how many speakers he wants per event. So I'm adding the nested fields gem and making speakers a nested field, as per their documentation.

事件.rb

class Event < ActiveRecord::Base
  has_many :speakers
  accepts_nested_attributes_for :speakers, allow_destroy: true
end

扬声器.rb

class Speaker < ActiveRecord::Base
  belongs_to :event
end

添加扬声器(在我的添加事件 simple_form_for 中):

Adding speakers (inside my add event simple_form_for):

  <%= f.nested_fields_for :speakers do |f| %>
      <fieldset class="item">
        <%= f.label :name %>
        <%= f.text_field :name %>

        <a href="#" class="remove">remove</a>

        <%= f.hidden_field :id %>
        <%= f.hidden_field :_destroy %>
    </fieldset>
  <% end %>

更新强参数的控制器:

private

  def event_params
    params.require(:event).permit(:title, :description, :type_id, :price, :program,
                                  :start_date, :end_date, :image, category_ids: [],
                                  speakers_attributes: [ :name ])
  end

现在,当我启动我的应用程序时,在创建我收到的新事件时:

Now when I launch my app, upon creation of the new event I'm getting:

can't write unknown attribute `event_id'

如果我删除

speakers_attributes: [ :name ]

根据强大的参数,我将能够创建我的事件,但是在尝试查看或编辑它时,我会得到

from the strong parameters I will be able to create my event, however when trying to view or edit it I will get

SQLite3::SQLException: no such column: speakers.event_id: SELECT "speakers".* FROM "speakers"  WHERE "speakers"."event_id" = ?

当然,数据库中没有创建扬声器.

And of course there are no speakers created in the database.

>> s = Speaker.first
=> nil

我将不胜感激任何帮助或建议.谢谢!

I will appreciate any help or advice. Thank you!

======

已更新重复问题

事件控制器

  def update
    @event = Event.find(params[:id])

    if @event.update(event_params)
      flash[:success] = "Event updated"
      redirect_to @event
    else
      render @event  
    end
  end

事件.rb

class Event < ActiveRecord::Base

  belongs_to :type

  has_many :categorizations
  has_many :categories, through: :categorizations
  has_many :speakers
  accepts_nested_attributes_for :speakers, allow_destroy: true

  @today = Date.today

  def self.future_events
    order('start_date ASC').where('start_date >= ?', @today)
  end

  scope :current_events,  lambda { where('start_date < ? and end_date > ?', @today, @today) }
  scope :past_events,     lambda { order('end_date DESC').where('end_date < ?', @today) }

  scope :future_by_type,   lambda { |type| order('start_date ASC').where('type_id = ? and start_date >= ?', type, @today) }
  scope :current_by_type,  lambda { |type| order('start_date ASC').where('type_id = ? and start_date < ? and end_date > ?', type, @today, @today) }
  scope :past_by_type,     lambda { |type| order('start_date ASC').where('type_id = ? and end_date < ?', type, @today) }

  validates :title, presence: true

  mount_uploader :image, ImageUploader

  before_save :define_end_date
  before_save :zero_price

    private

      def define_end_date
        self.end_date ||= self.start_date
      end

      def zero_price
        if self.price.empty?
          self.price = 0
        end 
      end
end

推荐答案

现在想想,可能跟强参数有关.为了更新工作,您还需要允许 id 属性.在您的许可参数中,为 speakers 和将更新的任何其他正在使用的嵌套嵌套资源添加 id.

Now that I think about it, it might be related to strong parameters. For update to work you need to allow id attributes also. In your permit params add id for speakers and any other nested nested resources in use that will be updated.

请试一试:

def event_params
  params.require(:event).permit(:title, :description, :type_id, :price, :program,
                              :start_date, :end_date, :image, category_ids: [],
                              speakers_attributes: [ :id, :name ])
end 

这篇关于嵌套字段和强参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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