Rails 5 - Понимание нового действия и ошибки рендеринга - PullRequest
0 голосов
/ 30 января 2019

Мои вопросы касаются раздела 5.10 официального Руководства по рельсам

У меня есть статьи модель с полями Заголовок и Текст

article.rb :

class Article < ApplicationRecord
  validates :title, presence: true, length: { minimum: 5 }
end

article_controller.rb :

class ArticlesController < ApplicationController

  def index
    @articles = Article.all
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def create
    @article = Article.new(article_params)

    if @article.save
      redirect_to @article
    else
      render 'new'
    end
  end

  private

  def article_params
    params.require(:article).permit(:title, :text)
  end
end

Руководствоговорит, что

@ article = Article.new

необходимо добавить к действию new , иначе @article будет нулевым, на наш взгляди вызов @article.errors.any? выдаст ошибку.Вот new.html.erb :

<%= form_with scope: :article, url: articles_path, local: true do |form| %>

  <% if @article.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@article.errors.count, "error") %> prohibited
        this article from being saved:
      </h2>
      <ul>
        <% @article.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>

  <p>
    <%= form.label :text %><br>
    <%= form.text_area :text %>
  </p>

  <p>
    <%= form.submit %>
  </p>

<% end %>

<%= link_to 'Back', articles_path %>

Я могу понять, что при возникновении ошибки она присутствует в @articles so @ article.errors.any?помогает в отображении ошибок при отображении «нового» представления.Это действительно работает, как и ожидалось, но я не могу понять, что @article = Article.new в новом действии должен сбросить @article, и ошибки должны быть потеряны после того, как пользователь будет перенаправлен на new.Но так или иначе, ошибки не теряются и действительно отображаются.Как это происходит?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

И render, и redirect - разные вещи.

  1. render Отображает содержимое, которое будет возвращено браузеру в качестве тела ответа.

  2. redirect или redirect_to -Перенаправление касается сообщения браузеру, что он должен сделать новый запрос в другое место или в то же место, которое указано в path.

Это четко упомянуто в artcle 5.10

Обратите внимание, что внутри действия create мы используем render вместо redirect_to, когда save возвращает false.Метод render используется для передачи объекта @article обратно в новый шаблон при его рендеринге.Этот рендеринг выполняется в том же запросе, что и отправка формы, в то время как redirect_to сообщит браузеру выполнить другой запрос.

Примечание: Вы можете прочитать render vsперенаправление подробно

По вашему вопросу

  def new
    @article = Article.new
  end

  def create
    @article = Article.new(article_params)

    if @article.save
      redirect_to @article
    else
      render 'new' # this will add  error (validations) 
    end
  end

  def create
    @article = Article.new(article_params)

    if @article.save
      redirect_to @article
    else
      redirect_to 'new' # this will not add any error as this is new request and @article will initialise again.
      new #same as redirect
    end
  end

Редактировать : Создание объектов формы с ActiveModel.Объект формы - это объект, специально разработанный для передачи в form_for

. Мы всегда проверяем ошибки @article.errors.any?, он будет выполняться, если @article объект содержит какие-либо сообщения об ошибках

Пожалуйста, прочитайте form_for Док.

0 голосов
/ 30 января 2019

render не запускает никакого кода в методе new, он просто использует представление new.html.x.Таким образом, @article = Article.new никогда не выполняется.

Если вы хотите запустить код из new, вам нужно вызвать этот метод:

def create
  @article = Article.new(article_params)

  if @article.save
    redirect_to @article
  else
    new #actually runs the code in the 'new' method
    render 'new' # doesn't go anywhere near the new method, just uses its view
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...