0

I would like to know what is the difference between @user and user, like in:

@user = User.new

and

user = User.new

Some people say that @user with @ is an instance used at views, but I already see this instance at Unit tests.

Is there any difference between then? In purpose or semantic or anything?

Lucas Andrade
  • 4,315
  • 5
  • 29
  • 50
  • 2
    Take a loot at [this post](https://stackoverflow.com/questions/3757481/rails-local-variables-versus-instance-variables). Perhaps it may helps you – Mikhail Katrin Dec 15 '17 at 12:42

2 Answers2

2

The instance @user at unit tests is not the same instance @user at controller, but they're used for similar reasons.

@ signify instance variables, which are available in all other methods of the instance object.

If in a controller you have

def new
  @user = User.new
  apply_another_value_to_user
end 

def apply_another_value_to_user
  @user.nickname = 'Zippy'
end

That works.

If instead you do...

def new
  user = User.new
  apply_another_value_to_user
end 

def apply_another_value_to_user
  user.nickname = 'Zippy'
end

You will get an error "undefined local variable or method 'user'" because user is only defined for use within the new method.

unit tests use @user to ensure a user object can be shared by different methods in the test instance. Controllers use @user to ensure a user object can be shared by different methods (and views) in the controller instance. It may be that during a test a controller instance is initialized and both @user instance variables happen to be created but they are not the same variable.

This is why in a test, to access a controller instance variable, you can't use @user directly, you have to use assigns(:user) which references the controller instance variable.

expects(assigns(:user).not_to be_nil
SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53
1

user is defined as local variable. You can reuse user with in the same method but cannot use it in other methods.

@user is instance variable. You can use it in other methods as well.

class SomeClass

  def first_method
    user = User.new
    @user = User.new
  end

  def second_method
    # ..
    # You can use @user here.
    # But user is undefined in this method. 
  end

end