Rails 3 - find_by не работает - PullRequest
       11

Rails 3 - find_by не работает

1 голос
/ 24 января 2012

У меня странная проблема.

У меня есть две модели: пользователи и роли, между которыми существует множество отношений. Я хочу отфильтровать роли с именем «Администратор» в коллекции ролей пользователя.

В модели этот код

puts self.roles.to_s

Печать на экран: [Идентификатор роли: 1, имя: «Администратор», create_at: «2012-01-22 21:55:45», updated_at: «2012-01-22 21:55:45»]

Но этот код

puts self.roles.find_by_name('Administrator').to_s

ничего не печатает. И этот:

puts self.roles.find_by_name('Administrator').nil?

печатает правда!

Почему мой метод find_by_name не работает? Я попробовал это в консоли, и это работает хорошо.

Мой фрагмент кода следующий:

puts self.roles.to_s
puts self.roles.find_by_name('Administrator').to_s
puts self.roles.find_by_name('Administrator').nil?

И вывод следующий:

[Role id: 1, name: "Administrator", created_at: "2012-01-22 21:55:45", updated_at: "2012-01-22 21:55:45"]
<none>
true

Что я делаю не так ?? Это должно быть что-то глупое. Этот код находится в методе validate, поэтому он выполняется перед сохранением пользователя.

1 Ответ

3 голосов
/ 24 января 2012

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

Причина, по которой работает первая строка (self.roles.to_s) заключается в том, что Rails запоминает любые роли, которые вы добавляете к своему пользователю, но не сохраняет их в базе данных, пока вы не сохраните пользователя.Как только вы сохраните пользователя, ваша вторая / третья строки будут работать нормально:

user = User.new
user.roles << Role.first
user.roles
# => [#<Role id: 1, name: "Administrator" ...>]
user.roles.find_by_name("Administrator")
# => nil
user.save  # This inserts both the new user AND the associations
user.roles.find_by_name("Administrator")
# => #<Role id: 1, name: "Administrator" ...>

Если вам придется работать с этим в проверках, вы можете попробовать использовать метод Enumerable find для поиска в rolesвместо массива:

user = User.new
user.roles << Role.first
user.roles
# => [#<Role id: 1, name: "Administrator" ...>]
user.roles.find { |role| role.name == "Administrator" }
# => #<Role id: 1, name: "Administrator" ...>
user.roles.find { |role| role.name == "Foo" }
# => nil
...