“Remember me” checkbox
最後,我們要來完成 Remember me 的 checkbox 功能了。架構如下:

首先,先在表單架構裡增加 checkbox 的 layout,如同文字、密碼和 email 欄位,checkbox 也可以使用 Rails 的輔助方法來建構:
<%= f.label :remember_me, class: "checkbox inline" do %>
<%= f.check_box :remember_me %>
<span>Remember me on this computer</span>
<% end %>
在 app/views/sessions/new.html.erb 加上 checkbox 的架構:
app/views/sessions/new.html.erb
<% provide(:title, "Log in") %>
<h1>Log in</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(:session, url: login_path) do |f| %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :remember_me, class: "checkbox inline" do %>
<%= f.check_box :remember_me %>
<span>Remember me on this computer</span>
<% end %>
<%= f.submit "Log in", class: "btn btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
然後撰寫 checkbox 的樣式:
app/assets/stylesheets/custom.css.sass
.
.
.
/* forms */
.
.
.
.checkbox
margin-top: -10px
margin-bottom: 10px
span
margin-left: 20px
font-weight: normal
#session_remember_me
width: auto
margin-left: 0
最後畫面會長這樣:
這個 checkbox 的功能就是如果勾選它,就記住使用者,反之就不要記住。因為我們之前的準備工作都做好了,所以現在只要一行程式碼就可以解決。提交表單的時候,params hash 會多一個 checkbox(remember_me) 的值:
session: !ruby/hash:ActionController::Parameters
email: ''
password: ''
remember_me: '1'
如果勾選了 checkbox,params[:session][:remember_me] 的值會是 1,反之為 0。
所以我們可以檢查 params hash 中相關的值,根據提交的值決定要不要記住使用者:
if params[:session][:remember_me] == '1'
remember(user)
else
forget(user)
end
也可以寫成一行,這種寫法是透過三元運算子(ternary operator):
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
把這個判斷述句加進 Sessions controller 裡的 create action:
app/controllers/sessions_controller.rb
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
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
三元運算子 - ternary operator
一般的 control flow 是這樣寫:
if boolean?
do_one_thing
else
do_something_else
end
但使用三元運算子,可以寫成這樣:
boolean? ? do_one_thing : do_something_else
也可以執行賦值,例如:
if boolean?
var = foo
else
var = bar
end
可以寫成這樣:
var = boolean? ? foo : bar
在函式中也常用三元運算子回傳值:
def foo
do_stuff
boolean? ? "bar" : "baz"
end