微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby – 变量范围定义和继承

我正在为我的网页开发扩展搜索功能.

我看了ransack,但是它缺少我需要的一些功能,使得url-query字符串很长并且有一些错误(报告).

因此我开始实施自己的黑客攻击.

首先,我想提出我的想法,之后我想问一下如何解决我的问题,最后是否有其他方法可以改善这个问题.

想法:

模型定义了这样的东西(另外,模型在引擎内):

module EngineName
  class Post < ActiveRecord::Base
    search_for :name,:as => :string do |b,q|
      b.where{name =~ "%#{q}%"}
    end
  end
end

:name用于定义要使用的查询参数,例如:这将是?q [name] =某事
我知道这不像ransack那样完全通用,但是……

:就像建立正确的表单标签一样. :string将用于text_field,:integer用于number_field,依此类推.我想进一步扩展它以实现为关联等自动生成集合.

现在该块是一个简单的使用范围.
在构建复杂查询时(比如count()等),我遇到了一些hansack的缺点.现在我可以在squeel中指定我自己的优化查询.

我扩展了ActiveRecord :: Base来设置逻辑(全局的,不在引擎内部.我想在任何地方使用它).
我定义了一个范围:搜索所以我可以像在ransack中一样使用Model.search(param [q]).
此外,我试图保留一个由search_for调用定义的“可搜索”键列表.

class ActiveRecord::Base
@@searchable_attributes = Hash.new({})

def self.search_for(name,*opts,&search_scope)
  return unless search_scope

  @@searchable_attributes[name] = {
    :type => opts[:as],:condition => search_scope
  }

  unless @@searchable_attributes.has_key? :nil
    @@searchable_attributes[:nil] = Proc.new { scoped }
  end
end

scope :search,lambda {|q|
  next unless q.kind_of?(Hash)

  base = @@searchable_attributes[:nil].call
  q.each do |key,search|
    next unless base.class.searchable_attributes.has_key?(key)
    base = @@searchable_attributes[key][:condition].call(base,search)
  end
  base
}
end

现在的问题:

它主要与类的继承有关.但即使在阅读并尝试3,4之后它也无效.

请查看范围中的第二行:搜索.

在那里,我称之为简单的Proc我在上面定义,其中只包括“范围”
这是为了解决自我返回“ActiveRecord :: Base”而不是像“Post”或“Comment”这样的模型本身的问题.

这是因为在继承上在Base类上调用了scope,但是我找不到任何解决这个问题的方法.

当在模型本身(例如Post)上调用search_for时,返回的范围模型是“正确的”.

有谁知道如何规避这个?

接下来的问题是,如何存储“可搜索”范围列表.我用@@变量.但是因为它们在每个子类中共享,所以这将是一个禁忌.
但是,它需要是静态的,因为在没有初始化实例的情况下调用search_for(不是吗?)

最后但并非最不重要的是,总是指定要在每个范围内使用的基础模型,以便我可以将它们链接在一起,这有点可怕.

还有其他可能性来改善这个吗?

解决方法

好吧,似乎我最终得到了它,我将其他问题的其他几个答案放在一起.

模型:

module EngineName
  class Post < ActiveRecord::Base
    searchable

    search_for :name,q|
     b.where{name =~ "%#{q}%"}
    end
  end
end

我的“插件”目前作为初始化程序:

class ActiveRecord::Base
  def self.searchable
    include Searchable
  end
end

module Searchable
  def self.included(base)
    base.class_eval {

      @@searchable_attributes = Hash.new({})

      def self.search_for(name,opts)
        return unless block_given?

        @@searchable_attributes[name] = {
          :type => opts[:as],:condition => Proc.new
        }
      end


      # Named scopes
      scope :search,lambda {|q|
        next unless q.kind_of?(Hash)

        base = self.scoped
        q.each do |key,search|
          key = key.to_sym
          next unless @@searchable_attributes.has_key?(key)
          base = @@searchable_attributes[key][:condition].call(base,search)
        end
        base
      }
    }
  end
end

希望它能帮助其他人解决同样的问题.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐