named_scope и .first? - PullRequest
       25

named_scope и .first?

4 голосов
/ 10 июня 2011

Я могу вернуть коллекцию объектов только с одним (: limit => 1), но есть ли способ вернуть только объект .first (), как не внутри коллекции?

named_scope :profile, :conditions => {:association => 'owner', :resource_type => 'Profile'}, :limit => 1    # => collection of 1 profile but I want the profile only NOT in a collection or array

Обходной путь - просто применить .first () к результатам, но я просто хотел бы очистить код и сделать его менее подверженным ошибкам.

Ответы [ 3 ]

7 голосов
/ 10 июня 2011

Возможно, вам вместо этого потребуется создать метод класса:

def self.profile
  where(:association => 'owner', :resource_type => 'Profile').first
end

Обратите внимание, что в Rails 3 вы должны использовать синтаксис where(...) и что при выполнении .first вам не нужнонеобходимо указать предел.

5 голосов
/ 10 июня 2011

Прежде всего, если вы используете Rails 3, вы должны использовать scope вместо named_scope. То же самое, другое, ошибочное имя (named_scope все равно будет работать, но не рекомендуется). Теперь, когда это не так ...

Область (или именованная область) принимает два аргумента (символ и лямбда или хеш) и определяет метод класса в этой модели, который возвращает ActiveRecord :: Relation, поэтому вы можете связывать методы на нем.

first, например find или all, возвращает фактический результат из базы данных. По этой причине это не будет работать в области видимости.

Все это говорит о том, что вы можете определить свой собственный метод класса в вашей модели, который дает желаемое поведение (поскольку 2 человека уже ответили, когда я набирал это). Это на самом деле рекомендуется, а не использовать области видимости многими уважаемыми разработчиками в сообществе Rails. Поскольку использование макроса класса scope просто в любом случае определяет сами методы класса, в этом нет и недостатка, и он обладает преимуществом гибкости (как в вашем случае здесь).

3 голосов
/ 10 июня 2011

Определите метод класса, чтобы сделать это:

def profile
  where(:association => "owner", :resource_type => 'Profile').first
end

first уже делает неявное limit 1 в запросе, И упорядочит его по первичному ключу таблицы, так что вы всегда получите первый.

...