rails 独学して軽くにちゃんまとめつくる

読者です 読者をやめる 読者になる 読者になる

rails独学して軽く2ちゃんまとめビルダーをつくる。

rails tutorial読破→2chまとめビルダー作成→アメリカでインターンシップ→恋活SNSを作成・・・・・→音で感触をつくり感触をあつめたライブラリをつくる

簡素なログイン機能

ログイン機能をリソースとして作られていることに注意する。セッションリソースでログイン画面を作成する。そこで得たメルアドとパスワードをデータベースから参照する。あれば、ログインする。

ログイン前後で表示を切り替えてはじめて役にたつ。

 

(new)フォームの作成
(create)コントローラーでのcreateアクションの条件分岐
ヘッダーをログイン前後で切り替え
(destroy)ログアウトの実行。ヘルパーで定義しておく。

ログインの神髄はhelperに定義されている関数だと思え。

log_in  current_user  logged_in?  log_out  の4つ

 

 

 

準備

$ rails generate controller Sessions new

 

ルーティング

get    'login'   => 'sessions#new'
post  'login'   => 'sessions#create'
delete 'logout'  => 'sessions#destroy'

 

app/controllers/sessions_controller.rb

 

 

ログインのビュー

<% 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.submit "Log in", class: "btn btn-primary" %>   
<% end %>    
<p>New user? <%= link_to "Sign up now!", signup_path %></p> 
</div>
</div>

 

 コントローラーの作成

セッションで受け取ったメルアドとパスワードをデータベースから参照している、と考えると何も難しくない。条件をパスしたらログインをしてやり、パスしなかったらメッセージとともにさようなら。

ただここで気にすべきは sessions コントローラーでも User モデルからデーターをもって来れるということ。

 

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
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

 

 ヘルパーの作成

log_in  current_user  logged_in? の3つを作る。log_in はまさに上でつくったコントローラーでつかったもん。残る2つはログイン前後でヘッダーの切り替えをさせるために定義するもん。

app/helpers/sessions_helper.rb

module SessionsHelper

  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
  end

  # 現在ログイン中のユーザーを返す (いる場合)
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  # ユーザーがログインしていればtrue、その他ならfalseを返す
  def logged_in?
    !current_user.nil?
  end
end

 

ヘルパーをすべてのコントローラーで使えるようにインクルードしておく

app/controllers/application_controller.rb

  include SessionsHelper

 

新規作成のときに同時にログインするようにしておく

def create



log_in @user

 

テストするときのための、ハッシュ化するメソッドを用意する

def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

 

ログアウト

 

コントローラーでの修正

 app/controllers/sessions_controller.rb

 def destroy

log_out
 redirect_to root_url
end

 

 

 

log_outメソッドの定義

app/helpers/sessions_helper.rb

module SessionsHelper
# 現在のユーザーをログアウトする
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end
end

 

コントローラーに付け足し。

def destroy
    log_out
    redirect_to root_url
  end

 

 

 

ビュー

で、これがそのヘッダー

app/views/layouts/_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", root_path, id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home", root_path %></li>
        <li><%= link_to "Help", help_path %></li>
        <% if logged_in? %>
          <li><%= link_to "Users", '#' %></li>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
              Account <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
              <li><%= link_to "Profile", current_user %></li>
              <li><%= link_to "Settings", '#' %></li>
              <li class="divider"></li>
              <li>
                <%= link_to "Log out", logout_path, method: "delete" %>
              </li>
            </ul>
          </li>
        <% else %>
          <li><%= link_to "Log in", login_path %></li>
        <% end %>
      </ul>
    </nav>
  </div>
</header>

 

 

 

app/assets/javascripts/application.js

//= require bootstrap

 

 

SSLを有効かする

コメントアウトされているので、 # を消すだけ。頑張って探せ。

 config/environments/production.rb

 config.force_ssl = true