【问题标题】:Rails3 Arel visits to custom classesRails3 Arel 访问自定义类
【发布时间】:2011-06-15 13:57:16
【问题描述】:

我有一个自定义类,但我希望能够将它传递给 Arel 并让它解析其 可查询 部分。

模块自定义 类项目 attr_accessor :名称 定义初始化(名称) self.name = 名称 结尾 结尾 结尾 custom_item = Custom::Item.new("Bill") User.where(:name => custom_item)

有什么我可以在 custom_item 中定义的,所以它会理解 Arel 想要从中命名?

目前我的解决方法是:

模块 Arel 模块访客 ToSql 类 def visit_Custom_Item o “'#{o.name}'” 结尾 结尾 结尾 结尾

【问题讨论】:

    标签: ruby ruby-on-rails-3 arel visitor-pattern


    【解决方案1】:

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

    当您尝试将自定义对象传递给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 功能的边界:)
    【解决方案2】:

    我可以通过为我的班级定义to_s 方法来规避这个问题

    class CustomItem
      def to_s
        custom_id
      end
    end
    

    并欺骗 Arel Visitor 将我的班级视为 Fixnum

    Arel::Visitors::Visitor::DISPATCH[CustomItem] = 'visit_Fixnum'
    

    使用 Rails 3.2.13。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 2018-02-12
      相关资源
      最近更新 更多