rails 4 强参数和 attr_accessor 的批量分配问题
rails 4 mass assignment issue with strong params and attr_accessor
因此,我在尝试对模型使用质量分配时发现了一个奇怪的问题,该模型还具有 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
而且我在更新对应的设备模型时,不会报错,但是更新方法后字段-department,entity会保持不变
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 强参数哈希将正确保存并且一切正常.我花了一段时间才弄清楚 attr_accessor 是导致批量分配失败的原因。
您的设备型号 已经 具有隐式 department_id
凭借此行:
belongs_to :department
通过 另外 声明 attr_accessor :department_id
您将用具体的 getter 和 setter 覆盖此隐式属性(及其 ActiveRecord 持久性魔法)基于 @department_id
实例变量(根本没有持久性魔法)。这可能不是你想要的。
因此,当您执行批量赋值时,@department_id
值会发生变化,但底层的 belongs_to
关联不会。因此,您观察到部门关联未在数据库中更新。
总而言之:您不需要 attr_accessor :department_id
因为 ActiveRecord 在您声明 belongs_to :department
.
时会自动生成类似的东西
因此,我在尝试对模型使用质量分配时发现了一个奇怪的问题,该模型还具有 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
而且我在更新对应的设备模型时,不会报错,但是更新方法后字段-department,entity会保持不变
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 强参数哈希将正确保存并且一切正常.我花了一段时间才弄清楚 attr_accessor 是导致批量分配失败的原因。
您的设备型号 已经 具有隐式 department_id
凭借此行:
belongs_to :department
通过 另外 声明 attr_accessor :department_id
您将用具体的 getter 和 setter 覆盖此隐式属性(及其 ActiveRecord 持久性魔法)基于 @department_id
实例变量(根本没有持久性魔法)。这可能不是你想要的。
因此,当您执行批量赋值时,@department_id
值会发生变化,但底层的 belongs_to
关联不会。因此,您观察到部门关联未在数据库中更新。
总而言之:您不需要 attr_accessor :department_id
因为 ActiveRecord 在您声明 belongs_to :department
.