Rails3 Arel访问自定义类

5
我有一个自定义类,但我想能够将其传递给Arel并让其解析其可查询部分。
module Custom
  class Item
    attr_accessor :name

    def initialize(name)
      self.name = name
    end
  end
end
custom_item = Custom :: Item.new(“ Bill”) User.where(:name => custom_item)
是否可以在custom_item中定义任何内容,以便它能理解Arel想要从中获取名称?
目前我使用以下方法解决:
module Arel
  module Visitors
    class ToSql
      def visit_Custom_Item o
        "'#{o.name}'"
      end
    end
  end
end
2个回答

5

我认为现在不可能。让我们试着找出原因。

当你试图将自定义对象传递给 where 方法时,比如 User.where(:name => custom_item),Arel 尝试调用 visit_YOUR_CLASS_NAME 方法(https://github.com/rails/arel/blob/master/lib/arel/visitors/visitor.rb#L15),但它失败了。然后 Arel 尝试调用 visit_ + object.class.ancestors.find {|klass| respond_to?(DISPATCH[klass], true)},但它再次失败,因为:

irb(main):001:0> class Foo
irb(main):002:1> end
=> nil
irb(main):003:0> foo = Foo.new
=> #<Foo:0x261edc0>
irb(main):004:0> foo.class.ancestors.map {|klass| p klass}
Foo
Object
Kernel
BasicObject
=> [Foo, Object, Kernel, BasicObject]

而 Arel 在这个列表中没有任何这些名称 https://github.com/rails/arel/blob/master/lib/arel/visitors/to_sql.rb#L394

alias :visit_ActiveSupport_Multibyte_Chars :quoted
alias :visit_ActiveSupport_StringInquirer  :quoted
alias :visit_BigDecimal                    :quoted
alias :visit_Class                         :quoted
alias :visit_Date                          :quoted
alias :visit_DateTime                      :quoted
alias :visit_FalseClass                    :quoted
alias :visit_Float                         :quoted
alias :visit_Hash                          :quoted
alias :visit_NilClass                      :quoted
alias :visit_String                        :quoted
alias :visit_Symbol                        :quoted
alias :visit_Time                          :quoted
alias :visit_TrueClass                     :quoted

实际上,我认为这不是一个非常有用的功能,但我已经向Aaron Patterson询问过了,如果他喜欢的话,我会尝试实现它。


想象一下,你有一个Rails 2应用程序,在其中你有这段代码将Arel无法访问的类传递给各个地方的查询,并且它能够正常工作,因为它们已经覆盖了to_s方法。但是在Rails 3中,所有这些都停止工作了。我知道这处于Rails / Arel功能的边缘 :) - Titas

3

我通过为我的类定义to_s方法来解决了这个问题。

class CustomItem
  def to_s
    custom_id
  end
end

欺骗Arel访问者将我的类视为Fixnum。
Arel::Visitors::Visitor::DISPATCH[CustomItem] = 'visit_Fixnum'

使用Rails 3.2.13进行工作。

对于类似字符串的值,您应该模仿String并使用visit_String


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接