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 ответа:
Я думаю, что это сейчас не возможно. Давайте попробуем выяснить, почему.
При попытке передать пользовательский объект в Метод
where
User.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
.