Ruby on rails 使用ActiveRecord:特定类的关系,而不是整个ActiveRecord的所有关系
我正在构建一个gem,其部分目的是扩展目标类上的关联。尽管我可以通过以下方式轻松扩展所有关联:Ruby on rails 使用ActiveRecord:特定类的关系,而不是整个ActiveRecord的所有关系,ruby-on-rails,ruby,activerecord,ruby-on-rails-4,gem,Ruby On Rails,Ruby,Activerecord,Ruby On Rails 4,Gem,我正在构建一个gem,其部分目的是扩展目标类上的关联。尽管我可以通过以下方式轻松扩展所有关联: ActiveRecord::Relation.send(:include, MyGem::ActiveRecord::RelationMethods) 这太宽泛了,对于可能使用此Gem的Rails应用程序,我不想扩展所有类的关联 为了获得更好的粒度,我想提供以下等效项: class User < ActiveRecord::Base has_many :messages, :ex
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
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
这是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'
难道你们不能重写类
中有许多方法(和类似的方法)来调用带有额外散列选项的原始实现吗?谢谢,这确实给了我一个想法。要在迭代ReflectionsThank phoet时设置“options[:extend]=MyGem::ActiveRecord::RelationMethods”,这是rails 4。设置选项[;扩展]不起作用。检查>User.reflections[:messages].options=>{:extend=>MyGem::ActiveRecord::RelationMethods}
时。如果未设置此选项,则无法访问新方法。我试图避免扩展每个关联方法有多个
,有一个
,等等,而只是扩展给定类中定义的任何关联。
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
# NoMethodError: undefined method `options' for nil:NilClass
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'