Проблема с поиском объекта класса в массиве классов - PullRequest
0 голосов
/ 14 июня 2011

Я использую Ruby on Rails 3.0.7, и я хотел бы понять, как обрабатывать следующий код для извлечения объектов класса с указанным id.

В моем файле просмотра у меня есть:

@records = Users.all # This returns an array (class)

В другом файле, частичном шаблоне, я бы хотел получить, например, пользователя с id 1, но если я сделаю это:

@records.find(1)

Я получаю enumerator (класс) всех записей:

<Enumerator: [<Users id: 1, ... ] >

Как мне найти пользователя с id 1 (или другими идентификаторами) "a la Ruby on Rails Way"?


UPDATE

Я использую @records = Users.all в файле представления, потому что я стремлюсь минимизировать обращения к базе данных , так как мне нужно перебрать почти все записи и проверить их существование. Если я сделаю, например:

some_hash.each { |key, value|
  put User.find(value)
}

и я захожу в файл журнала, я увижу много запросов к базе данных.

Ответы [ 4 ]

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

Несмотря на то, что это, вероятно, довольно медленно, и я подозреваю, что в приложении, над которым вы работаете, есть не совсем оптимальный дизайн (не судя, мы все там были), Array # index кажется, что вы ищете:

@records[@records.index{|user| user.id == 1}]

Редактировать

Хотя если вам нужно что-то сделать для каждого пользователя, и вам нужно быстро получить к ним доступ по идентификатору, я бы, вероятно, сделал что-то подобное в вашем контроллере. Даже если это не очень быстро, это намного более читабельно (для меня в любом случае):

@users_hash = {}
User.all.each{|user| @users_hash[user.id] = user}

Тогда в ваших взглядах вы можете сделать:

@users_hash[id].username
1 голос
/ 14 июня 2011

Используйте User.scoped вместо User.all. #all будет немедленно запрашивать базу данных и возвращать массив, тогда как #scoped будет возвращать ActiveRecord::Relation объект, который вы можете связать для дальнейших запросов. В этом случае база данных не будет поражена, пока вы не попытаетесь каким-либо образом проверить или перечислить результат

0 голосов
/ 03 мая 2013

В прошлый раз для такого случая я закончил так:

@assignments = Assignment.find_by_sql(' ... ')

@assignments.find(id: 1).first
0 голосов
/ 14 июня 2011

На самом деле вы ошибаетесь. @records.find(1) возвращает объект класса Enumerator (который отличается от самого класса Enumerator).

Проблема здесь в том, что, как вы заметили, @records является массивом, а не объектом ActiveRecord, а Array#find ( унаследован от Enumerable#find - что, когда не задано блок, возвращает объект класса Enumerable) - это не тот же метод, что и ActiveRecord::Base#find (то есть User#find).

В вашем контроллере нужно выбрать одну запись пользователя, которую вы хотите:

@user = User.find 1

... и затем используйте @user прямо в вашем шаблоне. Как правило, вам следует избегать поиска ActiveRecord (например, find) в ваших шаблонах. Такая логика должна происходить в вашем контроллере.

...