使用通用方法扩展多个模型的关联
Extending association of multiple models with common method
我希望能够使用通用代码从不同模型扩展多个关联,例如从 extending_relation_method
class 方法。但是我无法在这个方法中实现 self
成为关系对象。有什么建议么?谢谢。
module ModelMixin
extend ActiveSupport::Concern
module ClassMethods
def extending_relation_method
owner = proxy_association.owner
# some processing
self
end
end
end
class Model < ActiveRecord::Base
include ModelMixin
def self.test1
self
end
has_many :field_values, as: :owner, autosave: true do
# works
define_method :test1 do
self
end
# works
def test2
self
end
# do not work
define_method :test3, &(Model.method(:extending_relation_method).unbind.bind(self))
define_method :test4, &(Model.method(:extending_relation_method).unbind.bind(Model))
end
end
更新:
现在我认为问题可以简化为找出此行为的原因和解决方法:
proc1 = Proc.new { self }
def method_for_proc(*args)
self
end
proc2 = method(:method_for_proc).to_proc
1.instance_exec(&proc1)
#=> 1
# as expected
1.instance_exec(&proc2)
#=> main
# why??
通过将共享方法替换为共享过程解决了原始问题,但我想了解为什么会这样。
module ModelMixin
EXTENDING_RELATION_PROC = Proc.new do
owner = proxy_association.owner
# some processing
self
end
end
class Model < ActiveRecord::Base
has_many :field_values, as: :owner, autosave: true do
# works
define_method :test, &EXTENDING_RELATION_PROC
end
end
要调查您的 procs 问题,您可以在 to_proc
方法的源代码中查看注释 http://ruby-doc.org/core-2.2.0/Method.html#method-i-to_proc。所以 to_proc
不是通过方法主体创建新的 Proc
,而是通过调用此方法(在这种情况下绑定到 main
)。
但我认为在您的具体情况下,最好这样写:
module ModuleMixin
def extending_relation_method
# some processing
self
end
end
class Model < ActiveRecord::Base
has_many :field_values, as: :owner, autosave: true do
include ModuleMixin
end
end
我希望能够使用通用代码从不同模型扩展多个关联,例如从 extending_relation_method
class 方法。但是我无法在这个方法中实现 self
成为关系对象。有什么建议么?谢谢。
module ModelMixin
extend ActiveSupport::Concern
module ClassMethods
def extending_relation_method
owner = proxy_association.owner
# some processing
self
end
end
end
class Model < ActiveRecord::Base
include ModelMixin
def self.test1
self
end
has_many :field_values, as: :owner, autosave: true do
# works
define_method :test1 do
self
end
# works
def test2
self
end
# do not work
define_method :test3, &(Model.method(:extending_relation_method).unbind.bind(self))
define_method :test4, &(Model.method(:extending_relation_method).unbind.bind(Model))
end
end
更新:
现在我认为问题可以简化为找出此行为的原因和解决方法:
proc1 = Proc.new { self }
def method_for_proc(*args)
self
end
proc2 = method(:method_for_proc).to_proc
1.instance_exec(&proc1)
#=> 1
# as expected
1.instance_exec(&proc2)
#=> main
# why??
通过将共享方法替换为共享过程解决了原始问题,但我想了解为什么会这样。
module ModelMixin
EXTENDING_RELATION_PROC = Proc.new do
owner = proxy_association.owner
# some processing
self
end
end
class Model < ActiveRecord::Base
has_many :field_values, as: :owner, autosave: true do
# works
define_method :test, &EXTENDING_RELATION_PROC
end
end
要调查您的 procs 问题,您可以在 to_proc
方法的源代码中查看注释 http://ruby-doc.org/core-2.2.0/Method.html#method-i-to_proc。所以 to_proc
不是通过方法主体创建新的 Proc
,而是通过调用此方法(在这种情况下绑定到 main
)。
但我认为在您的具体情况下,最好这样写:
module ModuleMixin
def extending_relation_method
# some processing
self
end
end
class Model < ActiveRecord::Base
has_many :field_values, as: :owner, autosave: true do
include ModuleMixin
end
end