gpt4 book ai didi

ruby-on-rails - 覆盖 ActiveRecord 对模型和集合的查找的最干净的方法是什么?

转载 作者:数据小太阳 更新时间:2023-10-29 07:42:20 25 4
gpt4 key购买 nike

我有覆盖 Ar 的查找方法的库代码。我还包含了所有关联类的模块,因此 MyModel.find 和 @parent.my_models.find 都可以工作并应用正确的范围。

我的代码基于 will_paginate 的:

a = ActiveRecord::Associations
returning([ a::AssociationCollection ]) { |classes|
# detect http://dev.rubyonrails.org/changeset/9230
unless a::HasManyThroughAssociation.superclass == a::HasManyAssociation
classes << a::HasManyThroughAssociation
end
}.each do |klass|
klass.send :include, Finder::ClassMethods
klass.class_eval { alias_method_chain :method_missing, :paginate }
end

我的问题是,我只想覆盖某些模型的查找器。目前我需要扩展所有模型共享的所有关联集合类。我知道我可以通过传递一个模块来扩展每个模型的关联:

has_many :things, :extend => SomeCustomMethods

但我的库基本上是 ActiveRecord 插件,所以我想要一个适用于模型和作用域集合的可插入查找器扩展的干净约定,而不影响应用程序中的所有模型。

最佳答案

您想覆盖 find_every ,这是最终将运行的 AR 方法 find_by_sql与相应的查询。重写 find不适用于定制的查找器,而且它更脆弱。

但是为了与其他插件兼容,您不能只重载此方法。取而代之的是,在做完你想做的事情后,给它起个别名并调用原来的实现:

module MyPlugin
def self.included(base)
class << base
alias_method :find_every_without_my_plugin, :find_every
def find_every(*args)
# do whatever you need ...
find_every_without_my_plugin(*args)
end
end
end
end

ActiveRecord::Base.send :include, MyPlugin

这将为所有类启用您的插件。您希望如何控制启用哪些模型?也许是标准的插件访问器?

class User < ActiveRecord::Base
my_plugin
end

为了支持这一点,您需要移动 class << base到类方法(因此 base 应该是 self )。喜欢:

module MyPlugin
def self.included(base)
class << base
base.extend ClassMethods
end
end

module ClassMethods
def my_plugin
class << self
alias_method :find_every_without_my_plugin, :find_every
# ...
end
end
end
end

关于ruby-on-rails - 覆盖 ActiveRecord 对模型和集合的查找的最干净的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/314786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com