Учебное пособие Майкла Хартла по Rails: User.find (1) после метода destroy показывает трассировку стека - PullRequest
2 голосов
/ 29 августа 2011

Я изучаю урок Майкла Хартла по Rails, в частности, главу 6:

http://ruby.railstutorial.org/chapters/modeling-and-viewing-users-one#sec:finding_user_objects

после того, как я выполнил команду User.find (1) после команды user.destroy, я получаю следующее сообщение об ошибке:

ruby-1.9.2-p290 :006 > User.find(1)
ActiveRecord::RecordNotFound: Couldn't find User with ID=1
    from /Users/me/.rvm/gems/ruby-1.9.2-p290@rails3/gems/activerecord-3.0.9/lib/active_record/relation/finder_methods.rb:304:in `find_one'
    from /Users/me/.rvm/gems/ruby-1.9.2-p290@rails3/gems/activerecord-3.0.9/lib/active_record/relation/finder_methods.rb:289:in `find_with_ids'
    from /Users/me/.rvm/gems/ruby-1.9.2-p290@rails3/gems/activerecord-3.0.9/lib/active_record/relation/finder_methods.rb:107:in `find'
    from /Users/me/.rvm/gems/ruby-1.9.2-p290@rails3/gems/activerecord-3.0.9/lib/active_record/base.rb:444:in `find'
    from (irb):6
    from /Users/me/.rvm/gems/ruby-1.9.2-p290@rails3/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in `start'
    from /Users/me/.rvm/gems/ruby-1.9.2-p290@rails3/gems/railties-3.0.9/lib/rails/commands/console.rb:8:in `start'
    from /Users/me/.rvm/gems/ruby-1.9.2-p290@rails3/gems/railties-3.0.9/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

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

Ответы [ 4 ]

2 голосов
/ 29 августа 2011

Поскольку вы новичок в программировании, одна ключевая вещь - внимательно посмотреть на сообщение об ошибке.

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

Теперь, чтобы разобрать последовательность ошибок.

В этом случае ошибка показывает, что у вас нет записи, согласно сообщению:

ActiveRecord::RecordNotFound: Couldn't find User with ID=1

Ошибка возникла из-за того, что вы пытались найти пользователя с идентификатором 1. Исходная операция:

User.find(1)

Который, согласно вашему комментарию, был обработан операцией «Уничтожить», удалив таким образом данные. Это, конечно, предполагает, что у вас была либо одна запись, либо вы запросили уничтожение этой одной записи. Конечно, как уже говорили другие, операция find вызывает исключение

API задокументирован в Rails API , и вам нужны подробности о методе поиска, который описывает:

Если для всех перечисленных идентификаторов не найдено ни одной записи, будет вызвано RecordNotFound.

Еще один хороший справочник: API Dock

1 голос
/ 29 августа 2011

Вы не получите исключение, если выполните

 User.first(:conditions => { :id => 1 })

Причина, по которой вы получаете исключение, заключается в том, что Rails предполагает, что если вы используете метод find (id), вы ожидаете, что такой объект существует.Если нет объекта с данным идентификатором, он обрабатывает его как ошибку и возникает исключение.С другой стороны, если вы используете метод .first и пишете условие, вы не сообщаете rails, что ожидаете, что этот объект существует, а может и нет, поэтому в этом случае исключение не вызывается.Это немного сложно :) надеюсь, это немного понятно, почему вы получаете исключение в вашем случае, а не с тем, который я написал.Это просто вопрос интерпретации вашего ожидания.

0 голосов
/ 29 августа 2011

Вы также можете перехватить исключение и предпринять другие действия, если запись не найдена.Как то так:

begin
  @user = User.find(id)
  respond_with @user
rescue ActiveRecord::RecordNotFound
  flash[:alert] = "User with id = #{id} not found"
  redirect_to users_path
end
0 голосов
/ 29 августа 2011

find приводит к возникновению ошибки при сбое, тогда как find_by_<attribute here> методы просто возвращают nil. Так что в этом случае вы можете использовать find_by_id, который будет возвращать ноль вместо трассировки стека.

...