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).