我正在构建一个gem,其目的之一是扩展目标类的关联。虽然我可以通过使用类似的东西轻松扩展所有关联:
ActiveRecord::Relation.send(:include, MyGem::ActiveRecord::RelationMethods)
这太宽泛了,对于可能使用这个Gem的Rails应用程序,我不想扩展所有类的关联。
为了更好的粒度,我想提供相应的:
class User < ActiveRecord::Base
has_many :messages, :extend => MyGem::ActiveRecord::RelationMethods
has_many :comments, :extend => MyGem::ActiveRecord::RelationMethods
end
使用
class User < ActiveRecord::Base
acts_as_my_fancy_gem
has_many :messages
has_many :comments
end
当我将acts_as_my_fancy_gem
添加到类中时,我遇到的问题是尝试在Gem中有条件地扩展关联。这是它的基础。
module MyGem
extend ActiveSupport::Concern
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_my_fancy_gem
include MyGem::InstanceMethods
end
end
module InstanceMethods
...
end
end
我已经研究过反射,但此时可以找到一条清晰的路径,并且只是在黑暗中进行实验。
更新:
目前,我可以通过提供像
这样的类方法来实现每个关联class User < ActiveRecord::Base
has_many :messages
has_many :comments
fancy_extend :messages
end
module MyGem
extend ActiveSupport::Concern
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_my_fancy_gem
include MyGem::InstanceMethods
end
def fancy_extend *associations
class_eval do
associations.each do |association|
reflections[association].options[:extend] = MyGem::ActiveRecord::RelationMethods
end
end
end
end
module InstanceMethods
...
end
end
将这种方法添加到act_as_my_fancy
方法(我想要它的地方)中,这给了我:
# NoMethodError: undefined method `options' for nil:NilClass
答案 0 :(得分:1)
这是轨道4吗?我没有找到记录的:extend
选项。看起来rails 4现在使用块来做到这一点。
可能就是这么简单:
module Fancy
def has_many(name, scope = nil, options = {})
super(name, scope, options) do
def doit
"i did"
end
end
end
end
# in your model
extend Fancy
YourModel.your_relation.doit # => 'i did'