I came across 2 rather similar codes while doing Hartl's Tutorial. In Listing 8.25,the show
returns an instance variable @user
which is obtained by Rails's find
method.
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
log_in @user
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
In Listing 8.30, there is a similar situation in create
, which uses find_by
and should return an instance variable too, but this time it was defined as user
instead of @user
. I don't really know when to use @
and I also observe that both are controllers, so I would think the syntax should be consistent. Is there a reason for this discrepancy and in general, when are we allowed or not allowed to use @
to define instance variables?
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out
redirect_to root_url
end
end
A side question that I have would be, am I right to conclude that any methods defined in controllers are definitely class methods, hence the need for User.new
, while in models where we need to define methods, due to the extra flexibility provided, we need to declare explicitly during implementation whether it's a class method def User.new_token
or it's an instance method(def remember
).