简体   繁体   English

带有globalize2的searchlogic?

[英]searchlogic with globalize2?

Given there is a model: 给定一个模型:

class MenuItem < ActiveRecord::Base
  translates :title
end

and searchlogic is plugged in, I'd expect the following to work: 并且插入了searchlogic,我希望以下方法能够正常工作:

>> MenuItem.search(:title_like => 'tea')

Sadly, it doesn't: 可悲的是,它没有:

Searchlogic::Search::UnknownConditionError: The title_like is not a valid condition. You may only use conditions that map to a named scope

Is there a way to make work? 有办法工作吗?


PS The closest I managed to get workging, was: 附言:我最努力工作的是:

>> MenuItem.search(:globalize_translations_title_like => 'tea')

Which doesn't look nice. 哪个看起来不太好。

I developed searchlogic. 我开发了searchlogic。 By default, it leverages existing named scopes and the database columns. 默认情况下,它利用现有的命名作用域和数据库列。 It can't really go beyond that because ultimately it has to create the resulting SQL using valid column names. 它实际上不能超出范围,因为最终它必须使用有效的列名来创建结果SQL。 That said, there really is no way for searchlogic to cleanly understand what your :title attribute means. 就是说,searchlogic确实无法彻底了解您的:title属性的含义。 Even if it did, it would be specific to the logic defined in your translation library. 即使这样做,它也将特定于翻译库中定义的逻辑。 Which is a red flag that this shouldn't be in the library itself, but instead a plugin or code that gets initialized within your app. 这是一个危险信号,它不应该出现在库本身中,而是应该在您的应用程序中初始化的插件或代码。

Why not override the method_missing method and do the mapping yourself? 为什么不重写method_missing方法并自己进行映射? Searchlogic provides and easy way to alias scoped by doing alias_scope: Searchlogic通过执行alias_scope提供了一种简单的方法来确定范围:

alias_scope :title_like, lambda { |value| globalize_translations_title_like(value) }

Here's a quick stab (this is untested): 这是一个快速刺(未经测试):

module TranslationsMapping
  def self.included(klass)
    klass.class_eval do
      extend ClassMethods
    end
  end

  module ClassMethods
    protected
      def method_missing(name, *args, &block)
        translation_attributes = ["title"].join("|")
        conditions = (Searchlogic::NamedScopes::Conditions::PRIMARY_CONDITIONS + 
          Searchlogic::NamedScopes::Conditions::ALIAS_CONDITIONS).join("|"))

        if name.to_s =~ /^(#{translation_attributes})_(#{conditions})$/
          attribute_name = $1
          condition_name = $2
          alias_scope "#{attribute_name}_#{condition_name}", lambda { |value| send("globalize_translations_#{attribute_name}_#{condition_name}", value) }
          send(name, *args, &block)
        else
          super
        end
      end
   end
end

ActiveRecord::Base.send(:include, TranslationsMapping)

Hope that helps. 希望能有所帮助。 Again, I haven't tested the code, but you should get the general idea. 同样,我还没有测试代码,但是您应该大致了解。 But I agree, the implementation of the translations should be behind the scenes, you really should never be typing "globalize_translations" anywhere in your app, that should be take care of transparently on the model level. 但是我同意,翻译的实现应该在幕后,您绝对不应该在应用程序的任何位置键入“ globalize_translations”,这应该在模型级别上透明地进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM