Некоторые разработчики думают о redirect_to как о своей команде goto, перемещая исполнение из одного места в другое в вашем Rails-коде. Это неверно. Ваш код перестает работать и ждет нового запроса для браузера. Просто случается, что вы сказали браузеру, какой запрос он должен сделать дальше, отправив код статуса HTTP 302.
Рассмотрим эти действия, чтобы увидеть разницу:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
render action: "index"
end
end
С кодом в такой форме, вероятно, будет проблемой, если переменная @book
равна нулю. Помните, что render :action
не запускает какой-либо код в целевом действии, поэтому ничто не будет настраивать переменную @books, которая, вероятно, потребует индекс. Один из способов исправить это перенаправить вместо рендеринга:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
redirect_to action: :index
end
end
С помощью этого кода, браузер сделает свежий запрос индексной страницы, код в методе индекса будет работать, и все будет хорошо.
Единственный недостаток этого кода в том, что он требует двусторонней поездки в браузер: браузер запросил действие шоу с помощью/books/1, и контроллер обнаружил, что книг нет, поэтому контроллер отправляет перенаправление 302 ответ на браузер, говорящий ему перейти в/books /, браузер отвечает и отправляет новый запрос обратно на контроллер, запрашивая теперь действие индекса, контроллер затем получает все книги в базе данных и отображает шаблон индекса, отправляет его вернитесь к браузеру, который затем отобразит его на экране.
Хотя в небольшом приложении эта добавленная задержка может не быть проблемой, нужно подумать о том, является ли время отклика проблемой. Мы можем продемонстрировать один из способов справиться с этим с надуманным примером:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
@books = Book.all
flash.now[:alert] = "Your book was not found"
render "index"
end
end
Это определит, что нет книг с указанным идентификатором, заселить @books переменного экземпляра со всеми книгами в модели, а затем непосредственно визуализируйте шаблон index.html.erb, возвращая его в браузер с сообщением о флэш-оповещении, чтобы сообщить пользователю, что произошло.
В дополнение к его ответу, посмотрите на это для справки: http://guides.rubyonrails.org/v2.3.8/layouts_and_rendering.html#using-partials – David
Хорошо спасибо, но все-таки какая разница между Render и Yield в макете ? Они оба вставляют HTML? –
Таким образом, рендер и доходность рендеринга HTML и его вставка? –