rails 4使用强params和attr_accessor进行质量分配问题

时间:2015-07-10 20:56:04

标签: ruby-on-rails ruby-on-rails-4 activerecord strong-parameters

所以我在尝试在模型上使用质量赋值时发现了一个奇怪的问题,该模型对于通过质量指定的强params散列更新的属性也有attr_accessor。我很好奇为什么会发生这种情况 - 它应该发生吗?

这是我的控制器更新方法和强参数 -

  def update
    @device = Device.find(params[:id])
    if @device.update(device_params)
      redirect_to device_path(@device)
    else
      render :edit
    end
  end

  private

  def device_params
    params.require(:device).permit(:department_id, :entity_id, :description, :device_model_id)
  end

当我在更新的相应设备模型中执行此操作时,它不会抛出任何错误,但更新方法后字段 - 部门和实体将保持不变。

class Device < ActiveRecord::Base
  attr_accessor :device_event, :sensor_event, :department_id

  delegate :name, to: :department, prefix: true, allow_nil: true
  delegate :name, to: :entity, prefix: true, allow_nil: true
  delegate :id, to: :department, prefix: true, allow_nil: true
  delegate :id, to: :entity, prefix: true, allow_nil: true
  delegate :firmware, to: :device_configuration, prefix: true, allow_nil: true
  delegate :sleeptime, to: :device_configuration, prefix: true, allow_nil: true

  has_many :sensors
  has_many :events
  has_many :sensor_data, through: :events
  has_many :device_data, through: :events
  belongs_to :device_type
  belongs_to :entity
  belongs_to :department
  has_one :device_configuration

  paginates_per 10

  def self.filter(params_hash)
    filter_params = ActiveSupport::HashWithIndifferentAccess.new(params_hash)
    devices = Device.where(filter_params)
  end

  def recent_sensor_event
    self.events.where(event_type_id: 1).last
  end

  def recent_device_event
    self.events.where(event_type_id: 0).last
  end
end

现在,当我删除department_id上的attr_accessor时,在控制器中调用@ device.update并且一切正常时,mass_assigned强params散列将正确保存。我花了一段时间才弄清楚attr_accessors正在掀起大规模任务。

1 个答案:

答案 0 :(得分:1)

您的设备型号已经凭借此行隐含department_id

belongs_to :department

通过另外声明attr_accessor :department_id你用一个基于@department_id实例变量的具体getter和setter覆盖这个隐式属性(及其ActiveRecord持久性魔法)根本没有持久性魔法。这可能不是你的想法。

因此,当您执行质量分配时,@department_id值将会更改,但基础belongs_to关联不会更改。因此,您观察到部门协会未在数据库中更新。

总结一下:您不需要attr_accessor :department_id,因为当您声明belongs_to :department时,ActiveRecord会自动生成类似的内容。