1. we will first finish the create action:
def create
user = User.authenticate(params[:session][:email],
params[:session][:password])
if user.nil?
flash.now[:error] = "Invalid email/password combination."
@title = "Sign in"
render 'new'
else
sign_in user
redirect_to user
end
end
for the below, we will write sign_in method!!!
2. start from TDD again!!!
describe SessionsController do
.
.
.
describe "POST 'create'" do
.
.
.
describe "with valid email and password" do
before(:each) do
@user = Factory(:user)
@attr = { :email => @user.email, :password => @user.password }
end
it "should sign the user in" do
post :create, :session => @attr
# Fill in with tests for a signed-in user.
end
it "should redirect to the user show page" do
post :create, :session => @attr
response.should redirect_to(user_path(@user))
end
end
end
end
3. in this section, we will need some methods that are need to in both controller and view,
for view, we can define the method in SessionHelpr, (the method in all helpers are viewable for all views.)
to make controller see this method, we just need to include this module into the controller.
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
end
4. session and cookies:
Because HTTP is a stateless protocol, web applications requiring user signin must implement a way to track each user’s progress from page to page. One technique for maintaining the user signin status is to use a traditional Rails session (via the special session function) to store a remember token equal to the user’s id:
session[:remember_token] = user.id
User.find_by_id(session[:remember_token])
module SessionHelper
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
self.current_user = user
end
end
cookies[:remember_token] = {:value => user.id, :expires => 20.years.from_now.utc}
User.find_by_id(cookies[:remember_token])
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
self.current_user = user
redirect_to current_user
it "should sign the user in" do
post :create, :session => @attr
controller.current_user.should == @user
controller.should be_signed_in
end
controller.should be_signed_in
controller.signed_in?.should be_true
self.current_user = user
def current_user=(user)
@current_user = user
end
def current_user
@current_user
end
attr_accessor :current_user
def current_user
@current_user ||= user_from_remember_token
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
end
def foo(bar, baz)
bar + baz
end
foo(*[1,2])
====> 3
cookies.signed[:remember_token] || [nil, nil]
def self.authenticate_with_salt(id, cookie_salt)
user = find_by_id(id)
(user && user.salt == cookie_salt) ? user : nil
end
this is very traditional rails code, you really should get used to it!!!
d. we still need to define the signed_in method.
def signed_in?
!current_user.nil?
end