Witam, dopiero zaczynam z Railsami, mógłby mi ktoś wyjaśnić jedną rzecz?
begin
@article = Article.find(params[:id])
rescue ActiveRecord::RecordNotFound
flash[:error] = "Couldn't find category with given ID"
redirect_to articles_path
end
if params[:review]
...
else
@review = @article.reviews.new
end
Nie rozumiem dlaczego wyjątek jest wyłapywany a mimo tego kod wykonuje się dalej i otrzymuję dla wywołania @article.reviews.new:
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.reviews
Analogiczny kod mam w innych kontrolerach i wszystko działa jak należy Z góry dzięki za odp.
Po pierwsze primo: wyjątki nie są instrukcjami sterującymi. Po drugie primo, jak zastąpisz przechwycenie wyjątku instrukcją sterującą “if”, to zobaczysz co masz źle. Po wykonaniu klauzuli rescue wykonuje Ci się dalsza część kodu kontrolera, w tym jest problem, wyjątki zarezerwuj dla sytuacji wyjątkowych!
begin
@article = Article.find(params[:id])
rescue ActiveRecord::RecordNotFound
flash[:error] = "Couldn't find category with given ID"
redirect_to articles_path
else
if params[:review]
...
else
@review = @article.reviews.new
end
end
Wtedy twój dalszy kod wykona się tylko jeśli wyjątek nie wystąpi.
Jeśli to jest kod całej akcji możesz też go zapisać bez begin:
def akcja
@article = Article.find(params[:id])
rescue ActiveRecord::RecordNotFound
flash[:error] = "Couldn't find category with given ID"
redirect_to articles_path
else
if params[:review]
...
else
@review = @article.reviews.new
end
end
Nie chcesz łapać takich błędów i przekierowywać na inną stronę. Lepszą reakcją (jeśli ktoś zmieni id w URL) jest grzeczne wywalenie się i zwrócenie kodu 404 a nie przekierowanie.
Wyszukiwarki oczekują takiego zachowania od Twojej aplikacji. Jeśli użyjesz przekierowania to zaczynają głupieć.