6
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsの使い方まとめ

Last updated at Posted at 2017-04-10

Railsインストール・プロジェクト作成

Railsインストール

$ gem install rails

プロジェクト作成

$ rails new hoge
MySQL使う場合
$ rails new hoge --database=mysql

モデル作成・マイグレーション

モデル

Controllerは複数形、modelは単数形。

$ rauls g model User name:string email:stringを実行すると、マイグレーションファイルが作成される。作成されたマイグレーションファイルをDBに反映されるために、$ rails db:migrateを実行する。

モデルの作成・削除

$ rails g model User name:string email:string
$ rails destroy model User

マイグレーションファイル作成が不要の場合

モデル作成時のマイグレーションファイルの作成が不要な場合、--migration falseをつける。

$ rails g model User --migration false

モデルの更新

モデルのフィールドを変更したい場合、下記でマイグレーションファイルを作成する。

$ rails generate migration add_index_to_users_email
$ rails db:migrate

既存DBからプロジェクト作成する場合

Rails - schema.rb(既存DBを使ったアプリ作成)

モデルのValidation

app/models/user.rb
class User < ApplicationRecord
  before_save { self.email = email.downcase }
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }
end

マイグレーション

$ rails db:migrate
$ rails db:migrate RAILS_ENV=production #本番環境DB作成
$ rails db:rollback #1つ前に戻る
$ rails db:migrate VERSION=0 #最初に戻る
$ rails db:migrate:reset #DBをリセット

Rails - マイグレーション

コントローラの作成・ルーティング

コントローラ作成・削除

$ rails g controller StaticPages home help
$ rails destroy controler StaticPage home help

ルーティング

resources :usersと書くと、usersの規定のルーティングが反映される。

config/routes.rb
Rails.application.routes.draw do
  root   'static_pages#home'
  get    '/help',    to: 'static_pages#help'
  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'
  resources :users
  resources :account_activations, only: [:edit]
end

規定のルーティング

規定のルーティングは下記。

HTTP Req URL action name
get /users index users_path
get /users/1 show user_path(user)
get /users/new new new_user_path
post /users create users_path
get /users/1/edit edit edit_user_path(user)
patch /users/1 update user_path(user)
delete /users/1 destroy user_path(user)

rails routes

ルーティングの状態を確認できる。

$ rails routes

Link

リダイレクトのときは、hoge_urlを使って、あとは、hoge_pathを使う。

<%= link_to "About", about_path %>

root_path -> '/'
root_url -> 'http://hoge.com/'
help_path -> '/help'
help_url -> 'http://hoge.com/help'

ユーザ登録・ログイン・アクセス制限

devise(ユーザ登録・ログイン)と、cancan(アクセス制限)というgemを使うことで、実現するのが割と一般的。

Railsコマンド

Rails Commandの短縮形

$ rails g (generate)
$ rails c (console)
$ rails s (server)
$ rails t (test)
$ bundle (bundle install)

gemfile -> bundle install

$ bundle install
$ bundle install --without production
$ bundle update

rails server

--environment productionをつけると本番環境になる。

$ rails s --environment production

Scaffold

scaffoldでモデル・コントローラ・規定のルーティングとかもろもろ作成される。Migration Fileも作成されると思う。migrateでテーブルにモデルの内容が反映される。

$ rails generate scaffold User name:string email:string
$ rails db:migrate

rails console

--sandboxを付けると、DBを更新しないモードになる。testをつけるとテスト環境になる。

$ rails c
$ rails c --sandbox
$ rails c test

irbの設定

この設定によりirbのプロンプトが簡潔な表示に置き換えられ、irbの邪魔な自動インデント機能がオフになります。

~/.irbrc
IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.conf[:AUTO_INDENT_MODE] = false

パスワードのハッシュ化

bcrypt追加

bcryptというハッシュ関数のgemが必要。

gem 'bcrypt', '3.1.11'

Modelに追記

Modelに、has_secure_passwordを追加する

app/models/user.rb
class User < ApplicationRecord
  .
  .
  .
  has_secure_password
end

出来るようになること

自動化半端ない。

  • セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
  • 2つのペアの仮想的な属性 (passwordpassword_confirmation) が使えるようになる。また、存在性と値が一致するかどうかのバリデーションも追加される 。
  • authenticateメソッドが使えるようになる (引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド) 。

ログインチェック

authenticateメソッででチェックできる。

>>user = User.find_by(email: 'hoge@hoge.com')
>>user.authenticate(password)
true

ログインメソッド

上記ログインチェックがTrueだったら、下記でログインさせることができる。

session[:user_id] = user.id

Helperに書く例

app/helpers/sessions_helper.rb
module SessionsHelper

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

ログイン用のSessionControllerの例

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

  def destroy
  end
end

ログイン中ユーザの取得

@current_user ||= User.find_by(id: session[:user_id])

上記は、下記と同じ。

@current_user = @current_user || User.find_by(id: session[:user_id])

Helperに書く例

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
end

View

Form

こんな感じ。cakephpより全然いいけど、どれも似ている。<%= render 'shared/error_messages' %>というのは、全Viewに対して有効なパーシャルを読み込んでいる。

app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: signup_path) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

上のパーシャル

app/views/shared/_error_messages.html.erb
<% if @user.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(@user.errors.count, "error") %>.
    </div>
    <ul>
    <% @user.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>

上記に対応するコントローラ

app/controllers/users_controller.rb
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
      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

flash message

flash[:success]でflash messageを登録できる。

Viewに表示させるためには、下記のようにする。

<% flash.each do |message_type, message| %>
  <div class="alert alert-<%= message_type %>">
    <%= message %>
  </div>
<% end %>

下記が出力されるようになる。

<div class="alert alert-success">Welcome to the Sample App!</div>

Helper

Controllerに関連付けすることで、Controllerに対応する全てのViewでHelperを利用できるようになる。(関連付けしないとデフォルトで全てのViewで使えるのかもしれない。)

app/helpers/users_helper.rb
module UsersHelper

  # 引数で与えられたユーザーのGravatar画像を返す
  def gravatar_for(user)
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
end

ControllerにHelperをインクルードする

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper
end

これをViewで使う。

app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<h1>
  <%= gravatar_for @user %>
  <%= @user.name %>
</h1>

Layout

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag 'application', media: 'all',
     'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',  
     'data-turbolinks-track': 'reload' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <% flash.each do |message_type, message| %>
      <div class="alert alert-<%= message_type %>"><%= message %></div>
    <% end %>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>

パーシャル

パーシャルはcakephpのelementみたいなやつ。

app/views/layouts/_shim.html.erb
<!--[if lt IE 9]>
  <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
  </script>
<![endif]-->
app/views/layouts/_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", '#', id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home",   '#' %></li>
        <li><%= link_to "Help",   '#' %></li>
        <li><%= link_to "Log in", '#' %></li>
      </ul>
    </nav>
  </div>
</header>

Asset

  • app/assets: 現在のアプリケーション固有のアセット
  • lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット
  • vendor/assets: サードパーティのアセット

Bootstrap + Sass

gem 'bootstrap-sass', '3.3.6'
app/assets/stylesheets/custom.scss
$ bundle
$ touch app/assets/stylesheets/custom.scss
@import "bootstrap-sprockets";
@import "bootstrap";

Debug

debug()をviewに追加する。

app/views/layouts/application.html.erb
<%= debug(params) if Rails.env.development? %>

開発環境

テスト(test)、開発(development)、本番(production)がある。デフォルトはdevelopment。railsにはRailsオブジェクトがあり、env属性がある。Rails.env.test?はテスト中ならtrueを返す。

SSL接続

本番環境のSSL接続を強制する。全てが簡単だ。httpでアクセスしたらhttpsにリダイレクトされるのかな。

config/environments/production.rb
Rails.application.configure do
  .
  .
  config.force_ssl = true
  .
  .
end
6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?