Raf*_*sta 6 activerecord overriding ruby-on-rails
我正在创建一个这样的foo对象:
@foo = Foo.new(foo_params)
@foo.bar = Bar.where(name: "baz").first_or_create
Run Code Online (Sandbox Code Playgroud)
但是我还需要做其他一些事情.所以,我想过重写Foo初始化方法来做这样的事情:
class Foo < ApplicationRecord
def initialize(*args, BarName)
@foo = super
@foo.bar = Bar.where(name: BarName).first_or_create
end
end
Run Code Online (Sandbox Code Playgroud)
并称之为:
@foo = Foo.new(foo_params, "baz")
Run Code Online (Sandbox Code Playgroud)
但是Foo是一个ApplicationRecord,似乎不建议覆盖ApplicationRecord初始化方法.
那怎么能这样呢?还有其他想法吗?这会初始化压倒一切吗?
您可以使用 after_initialize 回调并在必要时使用瞬态:
class Foo < ApplicationRecord
after_initialize :custom_initialization
attr_accessor :barname
def custom_initialization()
self.bar = Bar.where(name: self.barname).first_or_create
end
end
Run Code Online (Sandbox Code Playgroud)
应用程序记录自己的初始化应该负责设置barname,前提是它在参数中
您可以使用活动记录回调.但是,您将无法指定bar_name,并且将以某种方式需要从Foo属性中动态查找它.
如果该选项适用于您.添加到您的模型类似于以下代码.
after_initialize :set_bar
# some other code
def set_bar
name = # dynamicly_find_name
self.bar = Bar.where(name: name).first_or_create
end
Run Code Online (Sandbox Code Playgroud)
如果你真的需要指定bar_name,我建议为它创建一个方法.
Foo.new(params).with_bar
def with_bar(bar_name)
self.bar = Bar.where(name: BarName).first_or_create
end
Run Code Online (Sandbox Code Playgroud)