Rails3 Arel посещение пользовательских классов
У меня есть пользовательский класс, но я хочу иметь возможность передать его в 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 ответа:
Я думаю, что это сейчас не возможно. Давайте попробуем выяснить, почему.
При попытке передать пользовательский объект в Метод
whereUser.where(:name => custom_item)Arel попробуйте вызвать методvisit_YOUR_CLASS_NAME(https://github.com/rails/arel/blob/master/lib/arel/visitors/visitor.rb#L15 ) но это не удается. Тогда Арел попробуй позвонить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]И Арел не имеет ни одного из этих имен в этом списке 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
Я смог обойти эту проблему, определив Метод
to_sдля моего классаclass CustomItem def to_s custom_id end endИ обманывает посетителя Арела, чтобы относиться к моему классу как к Fixnum
Arel::Visitors::Visitor::DISPATCH[CustomItem] = 'visit_Fixnum'Работал с рельсами 3.2.13.
Для строкового значения вы, вероятно, должны имитировать
Stringи использоватьvisit_String.