2011-06-15 17 views
5

Tengo una clase personalizada, pero quiero poder pasarla a Arel y dejar que resuelva su parte consultable.Rails3 visitas de Arel a clases personalizadas

 
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) 

es que hay algo que pueda definir en custom_item, por lo que entendería que quiere Arel nombre de ella?

Actualmente me Solución alternativa con:

 
module Arel 
    module Visitors 
    class ToSql 
     def visit_Custom_Item o 
     "'#{o.name}'" 
     end 
    end 
    end 
end 

Respuesta

5

Creo que no es posible ahora. Tratemos de descubrir por qué.

Cuando se intenta pasar el objeto personalizado con el método whereUser.where(:name => custom_item) Arel intenta llamar a visit_YOUR_CLASS_NAME método (https://github.com/rails/arel/blob/master/lib/arel/visitors/visitor.rb#L15) pero fracasa. Entonces Arel intenta llamar a visit_ + object.class.ancestors.find {|klass| respond_to?(DISPATCH[klass], true)} pero vuelve a fallar debido a que:

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] 

y Arel no tiene cualquiera de estos nombres en esta lista 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 

En realidad, no creo es una característica muy útil, pero le pregunté a Aaron Patterson sobre esto y, si le gusta, intentaré implementarlo.

+0

Imagine que tiene una aplicación Rails 2 donde tiene este código que pasa las clases que Arel no puede visitar a las consultas en varios lugares, y funciona porque tienen to_s overriden. Y todo deja de funcionar en Rails 3. Sé que está en el límite de la funcionalidad de Rails/Arel :) – Titas

3

que fue capaz de eludir este problema definiendo to_s método para mi clase

class CustomItem 
    def to_s 
    custom_id 
    end 
end 

Y engañar a Arel visitante para tratar mi clase como Fixnum

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

Se trabajó con rieles 3.2.13.

Para obtener un valor de cadena similar, probablemente debería imitar String y usar visit_String.

Cuestiones relacionadas