【问题标题】:Nested fields and strong parameters嵌套字段和强参数
【发布时间】:2013-08-19 07:42:06
【问题描述】:

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

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

这是我在执行 accept_nested_attributes 之前的工作 event_controller 参数:

private

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

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

事件.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 中):

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

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

can't write unknown attribute `event_id'

如果我删除了

speakers_attributes: [ :name ]

通过强大的参数,我将能够创建我的事件,但是当尝试查看或编辑它时,我会得到 ​​p>

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

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

>> s = Speaker.first
=> nil

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

=====

更新了重复问题

事件控制器

  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

【问题讨论】:

  • 检查事项:您的扬声器表是否有 event_id 列?您是否进行了迁移?
  • 如果这是一个严重的参数问题,您很可能会看到错误提示“未允许的参数 -> 参数名称”。我会按照 vinodadhika 的建议查看 db 表。
  • @simonmorley 将 event_id 添加到扬声器表工作。我不明白为什么插件的文档中没有提到这一点。但是现在我面临一个新问题:在使用嵌套扬声器编辑和保存事件时,它会复制它们。没有任何删除的可能。又是强参数?
  • @vinodadhikary 将 event_id 添加到扬声器表工作。我不明白为什么插件的文档中没有提到这一点。但是现在我面临一个新问题:在使用嵌套扬声器编辑和保存事件时,它会复制它们。没有任何删除的可能。强参数?
  • @DenisG,不,我认为这不是强参数问题,请发布您的控制器的更新操作和您的型号代码。模型的原因是确保您没有任何可能导致此问题的过滤器。

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

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

请试一试:

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 

【讨论】:

  • 有效!但是我没有事件 :id 权限。我还在 speaker_attributes 数组中添加了 '_destroy',所以现在看起来像这样:speakers_attributes: [ :id, :name, '_destroy' ] 非常感谢
  • 我会将 :id 添加到事件中以防万一
  • @DenisG,不客气。为了以防万一,不需要在事件上添加 :id 。我会更新我的答案。
  • 很抱歉再次打扰您,但是您知道如何删除我为每个演讲者上传的嵌套图像吗?我尝试进一步嵌套,但失败了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
相关资源
最近更新 更多