Rails中更新模型时如何禁用重写的Accessor?
解决Rails模型重写访问器后无法直接更新字段的问题
方法1:直接使用write_attribute操作字段
在控制器中绕过重写的访问器,直接调用write_attribute设置数据库字段值,再执行其他属性的更新:
category.write_attribute(:foo, params[:foo]) category.update(bar: params[:bar], baz: params[:baz])
也可以合并为连贯操作:
category.assign_attributes(bar: params[:bar], baz: params[:baz]) category.write_attribute(:foo, params[:foo]) category.save
方法2:模型中拆分读取与写入逻辑
保留原有的回退读取逻辑,但单独拆分出方法,同时恢复默认的字段写入逻辑:
# Category模型 def foo_with_fallback _foo = read_attribute(:foo) _foo = competition.foo if _foo.nil? _foo end # 恢复默认的读写方法,让赋值直接操作字段 def foo read_attribute(:foo) end def foo=(value) write_attribute(:foo, value) end
之后在需要回退逻辑的视图或业务代码中,改用foo_with_fallback,控制器的更新代码无需改动。
方法3:用update_columns直接更新数据库(谨慎使用)
如果不需要触发模型验证、回调逻辑,可以用update_columns直接操作数据库,完全绕过模型层的访问器:
category.update_columns(foo: params[:foo]) category.update(bar: params[:bar], baz: params[:baz])
注意:该方法不会执行任何回调和验证,仅适用于无需这些逻辑的场景。
方法4:重写写入方法保留读取逻辑
保留原有的foo读取回退逻辑,同时重写foo=方法让其直接写入字段,控制器代码无需修改:
# Category模型 def foo _foo = read_attribute(:foo) _foo = competition.foo if _foo.nil? _foo end def foo=(value) write_attribute(:foo, value) end
内容的提问来源于stack exchange,提问作者Matrix
相关产品推荐
相关产品推荐

