module HasUrl
extend ActiveSupport::Concern
included do
attr_accessor :bar
end
def bar
0
end
end
class Foo < ActiveRecord::Base
include HasUrl
end
bar属性不存储在数据库中,但它在表单中使用(使用SimpleForm的f.input
)。我想覆盖此方法的getter,以便我可以根据其他属性设置bar
,并使表单正确预填充值。
问题是在这样的包含块中使用attr_accessor
会在Foo
类上设置getter。由于该模块包含在祖先链中Foo
之上,因此永远不会触及返回0的自定义bar
方法。
解决此问题的一种方法是
class Foo < ActiveRecord::Base
include HasUrl
def bar
super
end
end
但我想避免这一额外的步骤。我只是想要包含该模块,让它只是“工作”。另一个选择是在我的表单中使用不同的帮助器(f.input_field等)但是我不能利用SimpleForm的包装器。
模块#prepend也不能解决我的问题,因为HasUrl
还定义了一些其他的东西(特别是ActiveRecord回调)。如果我在前面,这些回调会导致错误:
NoMethodError: undefined method `_run_...__find__...__callbacks`
有没有办法解决这个错误,以便prepend可以工作?或者完全这样做的另一种方式?
答案 0 :(得分:7)
您确定要attr_accessor
吗? attr_writer
不会足够吗?
require 'active_support/all'
module HasUrl
extend ActiveSupport::Concern
included do
attr_writer :bar
end
def bar
0
end
end
class Foo
include HasUrl
end
p Foo.new.bar
无论如何,如果你真的想使用attr_accessor
,这应该可行:
require 'active_support/all'
module HasUrl
extend ActiveSupport::Concern
included do
attr_accessor :bar
define_method :bar do
0
end
end
end
class Foo
include HasUrl
end
p Foo.new.bar