Возврат `self` в методе класса ActiveRecord теряет косвенную ссылку

При определении метода класса в ActiveRecord, если я возвращаю self, косвенная ссылка теряется.

Я не уверен, что использую правильный словарь, так как я только изучаю Ruby on Rails, поэтому вот пример:

class User < ActiveRecord::Base
  has_many :orchids
end

class Orchid < ActiveRecord::Base
  belongs_to :user

  def self.search(query)
    if query.present?
      query = '%' + query.gsub(/\s+/, '%') + '%'
      where 'gender ILIKE :query OR variety ILIKE :query', query: query
    else
      # Problematic line:
      self
    end
  end
end

Используя приведенное выше определение, происходит следующее:

% User.last.orchids.count
   (0.8ms)  SELECT COUNT(*) FROM "orchids" WHERE "orchids"."user_id" = $1  [["user_id", 2]]
 => 0 

% User.last.orchids.search('').count
   (1.2ms)  SELECT COUNT(*) FROM "orchids"
 => 449 

% User.last.orchids.search('cat').count
   (1.2ms)  SELECT COUNT(*) FROM "orchids" WHERE "orchids"."user_id" = $1 AND (gender ILIKE '%cat%' OR variety ILIKE '%cat%')  [["user_id", 2]]
 => 0

Таким образом, возврат self, по-видимому, устраняет косвенную область действия «только орхидеи этого пользователя». Возвращение self означает, что я возвращаю класс Orchid вместо ActiveRecord::Relation?

Почитав немного в Интернете, я нашел о прицелах и почему я должен их использовать. Прицелы работают так, как я ожидаю, и сейчас я их использую. Я просто не понимаю, почему это ведет себя так при использовании определений методов класса.


person Thiago Negri    schedule 10.02.2016    source источник


Ответы (1)


Self вернет класс, потому что self — это класс. Поскольку область действия возвращает экземпляр ActiveRecord::Relation. Таким образом, метод Orchid.where создает и возвращает новый ActiveRecord::Relation, тогда как self просто возвращает сам класс.

Оба по-прежнему могут быть связаны с дополнительными областями, если вы выберете. Если вы действительно хотите вернуть AR::Relation, измените self на Orchid.none.

person james2m    schedule 11.02.2016