gpt4 book ai didi

ruby-on-rails - 如何阻止 meta_search 在我的模型上定义搜索?

转载 作者:行者123 更新时间:2023-12-01 10:05:57 24 4
gpt4 key购买 nike

我正在使用 active_admin 并将 meta_search 引入我的项目。 (我不想将其用于任何其他用途)。

它似乎在我所有的模型上定义了搜索方法,这意味着当我包含轮胎时,我不能使用它的搜索方法。

它定义方法的方式似乎也有些奇怪 - method_defined?说没有定义搜索方法,但是当我调用它时,我得到了 meta_search 方法。即使我在类中定义了自己的搜索方法,当我调用 Document.search 时,我仍然会得到 meta_search。

编辑:我对处理这类事情的一般方法很感兴趣——我已经通过使用 Model.tire.search 解决了这个特定问题(因为轮胎也可以通过这种方式访问​​),但我仍然讨厌那个我什至没有使用的 gem 会迫使我在项目的其余部分使用变通方法。

编辑:我不知道在答案的答案中包含代码块的好方法,所以我会把它放在这里。

# Meta_search loaded, tire is not
1.9.3p125 :001 > require "tire" #=> true
1.9.3p125 :002 > Document.send(:include, Tire::Model::Search)
=> Document(...)
1.9.3p125 :003 > Document.search
Document Load (2.1ms) SELECT "documents".* FROM "documents"
# I get meta_search, as I should


# Tire loaded (and the include Tire::Model::Search is inside the class definition), meta_search is not loaded
1.9.3p125 :001 > Document.search
# I get tire, as I should
1.9.3p125 :002 > require "meta_search" #=> true
1.9.3p125 :003 > Document.search
# I still get tire, all is well

# Tire loaded, meta_search is not loaded
1.9.3p125 :001 > require "meta_search" #=> true
1.9.3p125 :002 > Document.search
Document Load (1.8ms) SELECT "documents".* FROM "documents"
# I get meta_search, even though Document.search was already defined!

# Tire loaded, meta_search is not loaded, RAILS_ENV="production"
Loading production environment (Rails 3.2.2)
1.9.3p125 :001 > require "meta_search"
=> true
1.9.3p125 :002 > Document.search
# I get tire!

我对此的解释是,meta_search 如何在类尚未实际加载时检测是否已定义搜索存在错误。万岁!

最佳答案

相关的两行:

https://github.com/ernie/meta_search/blob/master/lib/meta_search.rb#L55

https://github.com/ernie/meta_search/blob/master/lib/meta_search/searches/active_record.rb#L46

我不认为这是一个错误,事情就是这样。

场景 3 在开发环境中,您不预加载模型。当您需要“meta_search”时,它将在 ActiveRecord::Base 上定义“search”。然后你说加载模型的 Document 将首先继承定义的搜索方法,因此当它包含 Tire 搜索模块时,它会将搜索别名为元搜索。

在生产模式(场景 4)和场景 2 中,您在元搜索之前预加载文档模型,因此 Tire 将定义搜索。现在需要元搜索只会对新加载的类产生影响。

可以看到,gem 的定义顺序不计算在内。但是你可以在 gem require 之后取消定义搜索方法。

# application.rb
# ...
Bundler.require(:default, Rails.env) if defined?(Bundler)
# now move search out of the way
ActiveRecord::Base.instance_eval { undef :search }

因此,我们随时加载模型类并包含轮胎,无论是在开发还是生产中,搜索都会正确地转到轮胎。

这并不理想,因为非轮胎模型的搜索方法不会委托(delegate)给元搜索,实际上它不会被定义。所以可能第二种解决方案是最好的:在这里你用一个在运行时检查轮胎的方法覆盖搜索方法:

class ActiveRecord::Base
def self.search(*args, &block)
if respond_to?(:tire)
tire.search(*args, &block)
else
metasearch(*args, &block)
end
end
end

这有帮助吗?

关于ruby-on-rails - 如何阻止 meta_search 在我的模型上定义搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10662251/

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