rails 技術ブログ

rails 技術ブログ

勉強したことをアウトプットしていきます

content_forを使ってページごとにページのタイトルを変更する

application.html.erbに各ページのタイトルを受け取れるよう、yieldを記述します

<title><%= full_title(yield(:title)) %></title>



application.html.erbのfull_titleメソッドが使えるよう、ヘルパーで定義します

module ApplicationHelper
  def full_title(page_title = '')
    base_title = 'タイトル'
    if page_title.empty?
      base_title
    else
      page_title + ' | ' + base_title
    end
  end
end

↓のように短く記述することも可能です(三項演算子)

module ApplicationHelper
  def full_title(page_title = '')
    base_title = '技術ブログ'

    page_title.empty? ? base_title : page_title + " | " + base_title
  end



③各ページのviewでcontent_forを使ってそのページにアクセスした時に表示させたいタイトルを記述します

<% content_for(:title, '登録ページ') %>

上記のようにした場合、app/views/users/newページにアクセスするとタイトル部分が登録ページ | 技術ブログと表示されます

errorメソッドを使ってエラーの詳細を表示させる

フラッシュメッセージを使い、「ユーザー登録ができませんでした」等なら上手くいかなかったことは伝えられるものの、どこがエラーで登録ができなかったのか、伝えられたらユーザーもわかりやすいですよね。
例:メールアドレスの蘭がブランク→メールアドレスを入力してください

railsはバリデーションを設定していると、モデルの検証時にエラーメッセージを自動で生成してくれているので、それを利用してエラーの詳細を表示させることができます。

やり方

①エラーメッセージを出力させるパーシャルを作成する

<% if object.errors.any? %>
<!-- エラーがあった場合にメッセージを表示させる -->
  <div class="alert alert-danger">
    <ul>
      <% object.errors.full_messages.each do |message| %>
      <!-- エラーメッセージを生成する -->
        <li><%= message %></li> 
        <!-- メッセージを出力させる -->
      <% end %>
    </ul>
  </div>
<% end %>

②エラーを表示させたいビュー(HTMLファイル)に先ほど作ったパーシャルの内容をrenderする

<%= render 'shared/error_messages', object: f.object %> 


エラーになると以下のように表示されるようになります。 f:id:terakura-aina:20201027105001p:plain

デコレーターの使い方

Draperを使用した際の使い方を説明します。
(railsでデコレーター層を使いたい時はDraperか、Active_Decoratorを使うのが一般的です)

①gemをインストールする

gem 'draper'


②bundle installする

$ bundle install


③以下のコマンドを実行する

$ rails generate draper:install

このコマンドを実行することでデコレーター層が追加される
rails generateで、対応させたいモデルのデコレーターを作成する

$ rails generate decorator ○○(モデル名)


⑤作成したデコレーターにメソッドを定義する
userモデルのデコレーターを作成した場合の例↓

class UserDecorator < Draper::Decorator
  delegate_all
# delegate_allは、userモデルのメソッドを全て呼び出せるようにするためのもの

  def full_name
    "#{object.last_name} #{object.first_name}"
  # delegate_allが定義されていれば`object.`を省略することも可能
  end
end


⑥viewで使う

<%= decorate.full_name %>

フラッシュメッセージを表示させる

フラッシュメッセージとは

カスタマーが会員登録やログインなどの処理を行った時に、それが正しく処理されたのかをわかりやすくするために表示させるメッセージのこと。

書き方

flash[:success] = '登録が完了しました'
このように書くだけ。
具体的な使い方はこんな感じ↓

def create
    @user = User.new(user_params)
    if @user.save
     flash[:success] = '登録が完了しました'
       # success: '登録が完了しました'
       # flash.success = '登録が完了しました'
       # どの書き方でも意味は同じ
      redirect_to login_path
    else
      flash.now[:danger] = '登録に失敗しました'
      # ページをリダイレクトさせる時にrenderを使う時はflash.nowと書く
      # flash.now.danger = '登録に失敗しました'と書いても同じ意味
      render 'new'
    end
end

renderを使うとコントローラを経由せずにビューを表示するので、HTTPリクエストが送られず、1回とカウントされないため、次のページにいくともう一度メッセージが表示されてしまいます。
そのためflash.nowと書くとその問題が解消されます。

flashのあとのキー[:success]について

Bootstrapを使っている場合はキーにいれる文字を変えると、メッセージの色や背景色を変えることができます。
[:success]→緑
[:info]→青
[:warning]→黄
[:danger]→赤

↑を適用する場合はapplication_controller.rbに一つ設定が必要です

add_flash_types :success, :info, :warning, :danger


Bootstrapを使っているとredirect_toとflashを1行で表示できる

Before

def create
    @user = User.new(user_params)
    if @user.save
     flash[:success] = '登録が完了しました'
      redirect_to login_path
    else
      flash.now[:danger] = '登録に失敗しました'
      render 'new'
    end
end

After

def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = '登録が完了しました'
      redirect_to login_path, success: '登録が完了しました'
    else
      flash.now[:danger] = '登録に失敗しました'
      render 'new'
    end
end

i18nによる日本語化対応の設定

①config/application.rbに以下の設定を追加

config.i18n.available_locales = %i[ja en]
#アプリケーションが対応している言語の設定(ja=日本語、en=英語)
config.i18n.default_locale = :ja
#デフォルトの言語を日本語に設定
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
#言語ファイルを階層ごとに設定できるようにするための設定



②gemファイルにgemを追加

gem 'rails-i18n'



③gemをインストール

$ bundle install



④config/localesの中にja.ymlファイルを追加し、情報を定義します
(アプリケーションが増えると1つのファイルで管理がしづらくなるので、↓のようにActiveRecordとViewで分けて作成することも可能)
※ymlファイルのインデントが少しずれているだけでもエラーになってしまうので、注意!

ja:
  activerecord:
    models:
      user: 'ユーザー'
      board: '掲示板'
    attributes:
      user:
        last_name: ''
        first_name: ''
        email: 'メールアドレス'
        password: 'パスワード'
        password_confirmation: 'パスワード確認'
ja:
  defaults:
    login: 'ログイン'
    register: '登録'
    logout: 'ログアウト'
  users:
    new:
      title: 'ユーザー登録'
      to_login_page: 'ログインページへ'
  user_sessions:
    new:
      title: 'ログイン'
      to_register_page: '登録ページへ'
      password_forget: 'パスワードをお忘れの方はこちら'
  boards:
    index:
      title: '掲示板一覧'
    new:
      title: '掲示板作成'
    bookmarks:
      title: 'ブックマーク一覧'
  profiles:
    show:
      title: 'プロフィール'



⑤viewに表示させる

<%= t('activerecord.models.user') %> 

例えば↑のように埋め込みをするとビューでは「ユーザー」と表示されます


form_withはちょっと特殊
上に習うと、form_withの中で使おうとした時に下記のような表記になります。

<%= form_with model: @user, local: true do |f| %>
  <%= f.label :email, t('activerecord.attributes.user.email') %>
  <%= f.email_field :email' %>

しかし、model: @userから勝手に「これはユーザーに関する記述だ」と判断してくれるため、以下のように省略することも可能です。

<%= form_with model: @user, local: true do |f| %>
  <%= f.label :email %>
  <%= f.email_field :email %>



human_attribute_nameとModel.model_name.human
ActiveRecord::Baseのクラスメソッド。多言語化対応が可能になる。
まだよく理解しきれていないので、改めて理解できたら更新します。
↓何となくわかっていること

User.model_name.human
# t(’activerecord.models.user’)と同じ

→「ユーザー」と表示される

User.human_attribute_name :email
# t('activerecord.attributes.user.email')と同じ

→「メールアドレス」と表示される

application.scssに特定のscssだけ読み込ませる方法

assets/stylesheetsの中にapplication.scssとは別にusers.scss等ファイルを追加した場合、appledation.scssで全て読み込むことができるよう、以下のように記述します。

 *= require_tree .
 *= require_self

*= require_tree .→app/assets/stylesheets以下の全CSSファイルを読み込む
*= require_self→application.scss自体をスタイルシートに含めることを指定する


ただ、この設定にすると同じディレクトリ内(stylesheets内)のCSSファイルを全て読み込んでしまうため、順番を指定したい時は@importを使います。


使い方↓

@import 'users';

rails genarateコマンドで不要なファイルを作成したくない時

rails generateコマンドを使うと必要なファイルを一度に生成してくれるため便利なものの、時には不必要なファイルも一緒に生成されてしまいます。  


例えば$ rails generate controllerを実行すると以下のようにファイルが作られます。

$ rails g controller boards

Running via Spring preloader in process 74459

      create  app/controllers/boards_controller.rb
      invoke  erb
      create    app/views/boards
      invoke  test_unit
      create    test/controllers/boards_controller_test.rb
      invoke  helper
      create    app/helpers/boards_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/boards.scss


もし作成したくないファイルがある場合はconfig/application.rbに設定を書き込みます。

module RunteqNormal
  class Application < Rails::Application

    config.generators do |g|
      g.skip_routes true      #routes.rbを変更しない
      g.helper false      #ヘルパーを作成しない
      g.test_framework false #テストファイルを作成しない
    end

  end
end


先ほどのコントローラを$ rails destroy controllerで削除し、もう一度$ rails generate controllerを実行すると、、、

$ rails g controller boards [01_basic_settings]

Running via Spring preloader in process 74706

      create  app/controllers/boards_controller.rb
      invoke  erb
      create    app/views/boards
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/boards.scss

作成されたファイルが減りました。