noggy’s blog

自分用の備忘録です。。。

9.2 [Remember me]チェックボックス

ここでは、[remember me]チェックボックスでログインを保持する方法を解説。

まず、ログインフォームにチェックボックスを追加するところから始める。チェックボックスはヘルパーメソッドで作成できる。
ただし、チェックボックスが正常に動作するためには、ラベルの内側に配置する必要がある。

<%= f.label :remember_me, class: "checkbox inline" do %>
 <%= f.check_box :remember_me %>←ここ
 <span>Remember me on this computer</span>
<% end %>

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 :emails %>
      <%= f.text_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>    

ここで、2つのCSSクラスcheckboxinlineを使っている。Bootstrapでは、これらをチェックボックスとテキスト「Remember me on this computer」として同じ行に配置。

スタイルを整えるため、もう少しCSSルールを追加する。
app/assets/stylesheets/custom.scss

.checkbox {
  margin-top: -10px;
  margin-bottom: 10px;
  span {
    margin-left: 20px;
    font-weight: normal;
  }
}

#session_remember_me {
  width: auto;
  margin-left: 0;
}

ログインフォームの編集は終了!あとは、チェックボックスがオンのときにユーザーを記憶し、オフのときには記憶しないようにする。この実装はわずか1行で終わる。ログインフォームから送信されたparamsハッシュには、既にチェックボックスの値が含まれているので。すなわち、

params[:session][:remember_me]

チェックボックスがオンのとき'1'になり、オフのとき'0'になる。うーん、paramsいい仕事するなー

このparamsハッシュの値を調べることにより、送信された値に基づいてユーザーを記憶したり忘れたりできる。すなわち、

if params[:session][:remember_me] == '1'
 remember(user)
else
 forget(user)
end

さらに、このコードは次のような「三項演算子(ternary operator)」を使うと1行で表すことができる

params[:session][:remember_me] == '1' ? remember(user) : forget(user)

このコードを使うと、Sessionsコントローラのcreateアクション内にあったremember meユーザーはコンパクトなコードになる。
controllers/sessions_controller.rb

  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