Как я могу заставить named_scope в Rails возвращать одно значение вместо массива?
Я хочу написать named scope, чтобы получить запись с ее идентификатора.
Например, у меня есть модель под названием Event
, и я хочу моделировать Event.find(id)
с использованием named_scope
для будущей гибкости.
Я использовал этот код в своей модели:
named_scope :from_id, lambda { |id| {:conditions => ['id= ?', id] } }
и я вызываю его из своего контроллера, например Event.from_id(id)
. Но моя проблема в том, что он возвращает массив объектов Event
вместо одного объекта.
Таким образом, если я хочу получить имя события, я должен написать
event = Event.from_id(id)
event[0].name
в то время как я хочу
event = Event.from_id(id)
event.name
Я делаю что-то не так здесь?
Ответы
Ответ 1
Как упоминает Дэмиен, использование настраиваемой области просто для поиска по ID не рекомендуется. Но чтобы ответить на ваш вопрос:
Поиск записей с помощью named_scope
всегда будет возвращать объект ActiveRecord::NamedScope::Scope
, который ведет себя как массив. Если есть только одна запись, возвращаемая вашим запросом, вы можете использовать метод first
для непосредственного получения объекта ActiveRecord, например:
event = Event.from_id(id).first
event.name # will work as you expect
Ответ 2
В этом случае я бы создал метод класса
def self.from_id(id)
self.find(id).first
end
Другой пример:
class Invoice
def self.number
self.find(:first,
:select => "max(number) As last, max(number)+1 As next",
:conditions => "type = 'SalesOrder'")
end
end
Такие методы лучше, чем named_scope. Вы можете вызвать Invoice.number.next
, лучше, чем named_scope
return Invoice.number[0].next
.
Ответ 3
Здесь нет необходимости использовать область. Вы можете просто сделать Event.find_by_id id
.
Разница между find
и find_by_id
заключается в том, что первый будет поднять ActiveRecordNotFoundException
, если запись не существует. Второй возвращает только нуль.
Написание области для получения записи по этому идентификатору является очень плохим идентификатором, поскольку это то, что уже предусмотрено из-за рельсов.