stackjlei
stackjlei

Reputation: 10035

What is the purpose of having an instance created inside new method of Rails?

Learning rails from the guide, but what is the reason for having an empty article instance in new? When you go to new, it just renders a form for you and then when you submit, it creates it with the new instance inside the create action. If there are errors, it returns that instance to the new view (form) correct? In the docs, it says the below:

The reason why we added @article = Article.new in the ArticlesController is that otherwise @article would be nil in our view, and calling @article.errors.any? would throw an error.

But why would @article be nil if you already have created an instance through the create action? Why would the new action need to create another instance that has the errors? Isn't the instance created by create with the errors the one that will be rendered in new?

//controller

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

Upvotes: 1

Views: 55

Answers (2)

Sajan
Sajan

Reputation: 1923

I am not an expert in explaining but I will try. To me, Rails use this way so that we will have to write less code and rails will handle rest of the things.

Here is what you do: Lets assume, your Article model has 2 attributes(columns) i.e title, text.

Controller:

def new
  @article = Article.new
end

And in your view:

<%= form_for @article do |f| %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

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

  <p>
    <%= f.submit %>
  </p>
<% end %>

So when you do this, rails knows that you are generating a form for @article which is a (empty) object of Article class.

So it generates appropriate HTML from the from helpers like <%= f.text_field :title %> with proper id and name so that it can be mapped later in create action.

You don't have a title attribute in model then it will throw an error. So you can not do like this:

<%= f.text_field :body %>

Because rails knows, this form is for Article and your article does not have any attribute(column) for body.

when the form generates, it does not have any idea about your create action. It knows about new action only.

So this is one of the reason behind initializing a new record for form.

I hope you got my point. Maybe someone else can explain better with any other reason behind this.

Upvotes: 2

Slava.K
Slava.K

Reputation: 3080

Rails runs only the code inside corresponding action when processing a request. So when user goes to /articles/new only new action is triggered and when user makes HTTP POST request to /articles only create action is called. Read rails guides on ActionController

Upvotes: 2

Related Questions