Массив :: включить? в коллекции ActiveRecord не вызывается op ==? - PullRequest
2 голосов
/ 12 марта 2010

Учитывая коллекцию именованных Foo s из ActiveRecord, почему Array#include?, кажется, не вызывает Foo.==, но все же index делает?

class Foo < ActiveRecord::Base
  def ==(s)
    self.name == s
  end
end

class Bar < ActiveRecord::Base
  has_many :foos
end

bar.foos << Foo.new( :name => 'hmm' )

bar.foos.all.include?('hmm')  # does select all from db every time
=> true

bar.foos.include?('hmm') # does not go to db, but does not find the Foo!
=> false

bar.foos.index('hmm') # does not go to db, but does find the Foo[0] !
=> 0

bar.foos.index('eh') # no such object
=> nil

Я хорошо понимаю, что такое прокси, но (без обхода источника AR) почему индекс ведет себя правильно, но включает? нет!?

Это ошибка в поведении прокси-сервера, и / или это поведение где-то задокументировано?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 12 марта 2010

Симона, это не тот ответ, который я ищу (но мне нравится, как ты думаешь; -)

Это побуждает меня прочитать документацию, т.е. исходный код association_proxy.rb (на самом деле AssociationCollection, который эмулирует методы Array для коллекции, возвращаемой ассоциацией.)

Глядя на AssociationCollection.include?

 File activerecord/lib/active_record/associations/association_collection.rb, line 332
      def include?(record)
        return false unless record.is_a?(@reflection.klass)
        load_target if @reflection.options[:finder_sql] && !loaded?
        return @target.include?(record) if loaded?
        exists?(record)
      end

Похоже, что arg record ожидается типа @reflection.klass, тогда как Array.include? берет объект и использует компаратор ==, определенный для объектов массива.

Ну, во всяком случае, это не то, что я хотел от AR. Так как Enumerable.member? кажется, работает над коллекцией ассоциаций, я просто буду использовать это. Я хочу просканировать кэшированную коллекцию и больше не попадать в базу данных. Может быть, кто-то мог бы объяснить, как AssociationCollection перераспределяет член?

0 голосов
/ 12 марта 2010

Это потому, что bar.foos не возвращает объект ActiveRecord::Base, но возвращает AssociationProxy (см. association_proxy.rb).

Я не предлагаю вам переопределить == в прокси-сервере ассоциации, иначе вы измените поведение всех ваших ассоциаций в вашем приложении.

...