Ruby 默认情况下如何转换ActiveRecord::关系
我正在从事一个项目,该项目需要对Ruby 默认情况下如何转换ActiveRecord::关系,ruby,activerecord,Ruby,Activerecord,我正在从事一个项目,该项目需要对ActiveRecord::Relation对象调用非常特定的方法。这些方法无法扩展ActiveRecord::Relation,因为Class有自己的initialize方法来确定是否应该收集对象。我已经尝试了十几种方法来处理这个问题,但是由于AR中的方法链接,我一直无法做到这一点。目前,我使用一种方法对其进行了如下转换: module ActiveRecord class Relation def to_claim_set exec_q
ActiveRecord::Relation
对象调用非常特定的方法。这些方法无法扩展ActiveRecord::Relation
,因为Class
有自己的initialize
方法来确定是否应该收集对象。我已经尝试了十几种方法来处理这个问题,但是由于AR
中的方法链接,我一直无法做到这一点。目前,我使用一种方法对其进行了如下转换:
module ActiveRecord
class Relation
def to_claim_set
exec_queries unless loaded?
ClaimSet.new(@records)
end
end
end
首先,我确信这是一种不恰当的处理方式。其次,这导致我必须在整个应用程序中不断调用#来_claim_set
我希望有人能在所有方法链接完成后帮助将此作为默认返回
我所希望的是
Claim.policy_number('913006')
#=> ClaimSetObjectHere
但是我需要它来支持链接,比如AR
这样做
Claim.policy_number('913006').by_program('Base')
#=> ClaimSetObjectHere
我还尝试在索赔
中修补#where
方法,除非我使用范围
或I-chain方法,在这种情况下,它会抱怨索赔集
没有定义默认范围?
如有任何见解,将不胜感激。至于“为什么要这样做”,就像我说的,我在整个应用程序中不断调用这个方法,我需要ClaimSet
中定义的方法才能正常工作
注意:这是在
rails
之外使用的,所以我最后做的是为ActiveRecord::Relation
添加一个包装器,如下所示:(为了简洁起见,删除了特定的业务逻辑)
然后在索赔
类中
class Claim < ActiveRecord::Base
class << self
def where(*args)
ClaimSet.new(super(*args))
end
def localized_scope(name,proc)
scope_proc = lambda do |*args|
ClaimSet.new(proc.call(*args))
end
singleton_class.send(:define_method,name,scope_proc)
end
end
end
现在,它总是返回一个索赔集
来代替的活动记录::关系
,其中
和#本地化范围
,并支持通过#方法(缺少
进行方法链接。它还删除了ActiveRecord::Relation
上的monkey补丁
如果你有任何其他建议,请让我知道,因为我会很高兴考虑其他想法,但这是暂时的工作
class Claim < ActiveRecord::Base
class << self
def where(*args)
ClaimSet.new(super(*args))
end
def localized_scope(name,proc)
scope_proc = lambda do |*args|
ClaimSet.new(proc.call(*args))
end
singleton_class.send(:define_method,name,scope_proc)
end
end
end
localized_scope :policy_number, ->(policy_number){where(policy_number: policy_number)}