Ray.Rai
Ray.Rai

Reputation: 43

Reason for adding an @user variable to the new action(def new @user = User.new end)

I am trying to build user signup form by following Michael Hart's Rubyonrails book. Chapter 7:Singup

However I simply couldn't wrap my head around this little piece of code.

def new 
    @user = User.new
  end

I want to know what is the purpose of the above code and how it works?

If I exclude above code (@user=User.new) deliberately, it'll throw error message saying:

raised: First argument in form cannot contain nil or be empty

If first argument in form cannot contain nil or be empty,why declaring @user=User.new get passed since it assign nil value to user object.My naive understanding of rails can be wrong here.

Here is the full code

controller/user_controller.rb

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end  

  def new 
    @user = User.new
  end

   def create
     @user = User.new(user_params)   # Not the final implementation!
    if @user.save
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user

    else
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end

views/users/new.html.erb

<%= form_for(@user) do |f| %> <%= render 'shared/error_messages' %>

  <%= f.label :name %>
  <%= f.text_field :name %>

  <%= f.label :email %>
  <%= f.text_field :email %>

  <%= f.label :password %>
  <%= f.password_field :password %>

  <%= f.label :password_confirmation, "Confirmation" %>
  <%= f.password_field :password_confirmation %>

  <%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>   </div> </div>

Before presenting this questions to respectable stackoverflow community I looked for the answer at the following links:-

http://railscasts.com/episodes/250-authentication-from-scratch

First argument in form cannot contain nil or be empty Hartl's Rails 4 Tutorial

In Ruby on Rails Restful Authentication, UsersController#new, a @user = User.new is used. Is it actually needed?

Thank you for your time.

Upvotes: 1

Views: 473

Answers (2)

metronom72
metronom72

Reputation: 171

When you type

@user = User.new

You create Model's object user with empty fields. This variable is instance variable for this object and you can access to it in your view and you use it in form fields

form_for(@user)

Fields in your form in view is specify fields of this variable, but variable cannot be nil. If you haven't variable @user, you may use any another variable and set it by symbol. Well variable for form_for must be instance variable( start with @ ) or specified in .erb file

When you submitting form, you send hash where variable has hash with fields for example params {"utf8"=>"✓", "authenticity_token"=>"xxx=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create user"}

Upvotes: 0

sameera207
sameera207

Reputation: 16629

What happens in the line

def new 
  @user = User.new
end

is, rails is creating an instance variable called @user (ruby uses @ sign for instance variables) and assigns a new User model. This could be most of the time the User model in

app/models/user.rb

and then it passes to your view #app/vies/users/new.html.erb.

and remember, initializing a new User object and assign in to @user is not same as assign nil value to the @user

Then comes your second question, Why its giving an error when you exclude it deliberately.

So the reason behind that is,

when u say @user = User.new and pass the @user variable to rails form_helper. (<%= form_for(@user) do |f| %>), so form_helper automatically dose some things for you,

If you get the html source for the page it will be like

<form action="/users" id="new_user" method="post"> </form>

it means rails form helper is creating the routes, post method (post) etc for you. from your line <%= form_for(@user) do |f| %>. As u may already understand now, if you just pass 'nilvia@user = nil, railsform_helper` cannot do all that processing stuff , thats why you are getting the above error.

read more about form helpers , HTH

Upvotes: 1

Related Questions