5
6

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.

基礎Ruby on Rails Chapter7 バリデーションと国際化

Last updated at Posted at 2018-09-25

基礎Ruby on Rails Chapter6 レコードの作成、更新、削除
基礎Ruby on Rails Chapter8 単数リソース

バリデーション

バリデーションとエラー情報

  • saveメソッドを呼び出すと、バリデーションを実行する。
  • Memberモデルに、validatesメソッドを加えてみる。
class Member < ApplicationRecord
  validates :number, presence: true
  • member.number=nilにして、保存してみると、saveメソッドがfalseを返している。
  • member.errors.messagesで、エラーの中身が見ることができる。{:number=>["can't be blank"]}
  • member.errors.empty?で、エラーオブジェクトの有無が確認できる。
  • member.errors[:number]で、属性ごとのエラー情報を取り出すことができる。
  • member.valid?は、エラーなし?という意味で、エラーがある場合、falseを返す。
  • member.invalid?は、エラーあり?という意味で、エラーがある場合、trueを返す。
irb(main):001:0> member = Member.first
  Member Load (0.4ms)  SELECT  "members".* FROM "members" ORDER BY "members"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<Member id: 1, number: 10, name: "Taro", full_name: "佐藤 太郎", email: "Taro@example.com", birthday: "1981-12-01", sex: 1, administrator: true, created_at: "2018-09-21 14:01:43", updated_at: "2018-09-21 14:01:43">
irb(main):002:0> member.number = nil
=> nil
irb(main):003:0> member.save
   (0.0ms)  begin transaction
   (0.1ms)  rollback transaction
=> false
irb(main):004:0> member.errors.messages
=> {:number=>["can't be blank"]}
irb(main):005:0> member.errors.empty?
=> false
irb(main):006:0> member.errors[:number]
=> ["can't be blank"]
irb(main):007:0>

validatesメソッドの書き方

  • validatesメソッドの引数には、シンボルでモデルの属性名を指定し、ハッシュでバリデーションの種類:trueを並べる。属性名、バリデーションともに複数並べられる。
  • バリデーションの種類:{オプション:オプションの値}とすると、バリデーションごとにオプションを指定できる。
validates :number, :name, presence: true
validates :name, length: { maximum: 20 }

会員情報の検証

app/models/member.rb(一部)
class Member < ApplicationRecord
  # numberのバリデート。nil,空,全角/半角空白禁止
  validates :number, presence: true,
    numericality: {
      # 整数のみ
      only_integer: true,
      # 0以上
      greater_than: 0,
      # 100未満
      less_than: 100,
      # presenceとの重複を避けるため
      allow_blank: true
    },
    # 重複禁止
    uniqueness: true
  # nameのバリデート。nil,空,全角/半角空白禁止
  validates :name, presence: true,
    # アルファベットから始まり、英数字のみ
    format: { with: /\A[A-Za-z][A-Za-z0-9]*\z/, allow_blank: true },
    # 2文字以上20文字以下
    length: { minimum: 2, maximum: 20, allow_blank: true },
    # 重複禁止
    uniqueness: { case_sensitive: false }
  # full_nameのバリデート。nil,空,全角/半角空白禁止。20文字以下
  validates :full_name, presence: true, length: { maximum: 20 }

メールアドレスのチェック

  • メールアドレスのチェックは複雑なので、既存のGemパッケージを利用する。
Gemfile
gem 'email_validator', '~> 1.6'
  • ctrl-cでRailsサーバを止めて、bundle installコマンドを実行する。サーバを起動しなおす。
$ bundle install
$ bin/rails s
app/models/member.rb(一部)
  # emailのバリデート
  validates :email, email: { allow_blank: true }

エラーメッセージの表示

  • エラー表示のテンプレートを作成する。
  • full_messagesは、エラーを出した属性+メッセージの配列を返す。
app/views/shared/_errors.html.erb
<% if obj.errors.present? %>
  <div id="errors">
    <h3>エラーがあります。</h3>
    <ul>
      <% obj.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>
  • 上記の部分テンプレートを表示する部分を、先頭に追加する。
  • obj: @memberで、_errors.html.erbのローカル変数objがモデルオブジェクトを参照するようにする。
app/views/members/_form.html.erb(一部)
<%= render "shared/errors", obj: @member %>
  • エラー表示用のCSSファイルを追加する。
  • エラーを起こした入力欄は、class属性がfield_with_errorsのdivタグで囲まれる。
app/assets/stylesheets:errors.css
/* エラー表示 */
div#errors {
  background-color: #fee;
  border: 1px solid #ecc;
  padding: 15px;
  margin: 0 0 1em;
}

div#errors h2 {
  font-size: 90%;
  color: red;
  margin: 0 0 4px;
  border: none;
}

div#errors ul {
  margin: 0;
  padding-left: 1.5em;
}

div.field_with_errors {
  background-color: #fcc;
  padding: 2px;
}

image.png

Railsの国際化機能

  • Railsの国際化機能は、I18nというクラスにロケールを設定し、ロケールに合わせてYAML形式のロケールテキストから文字列を読み込んで表示する。
  • ロケールを設定するには、コントローラでロケールを表す文字列やシンボルを設定する。
I18n.locale = "ja"
  • 指定がなければデフォルトのロケール「en」が使われる。
  • application.rbにデフォルトのロケールを設定する。
config/application.rb
config.i18n.default_locale = :ja

エラーメッセージの日本語化

Gemパッケージrails-l18n

  • Gemパッケージ「rails-i18n」は、さまざまな言語のためのエラーメッセージや日付の書式などを集めたもの。
  • Gemfileに追加する。
Gemfile
gem 'rails-i18n', '~> 5.1'
  • ターミナルでrails-i18nをインストールする。
$ bundle install

モデルの属性名の日本語化

  • 日本語テキストを記述する、ja.ymlを作成する。
config/locales/ja.yml
ja:
  activerecord:
    models:
      member: 会員情報
    attributes:
      member:
        number: 背番号
        name: ユーザー名
        full_name: 氏名
        sex: 性別
        sex_1: 
        sex_2: 
        birthday: 誕生日
        email: メールアドレス
        administrator: 管理者
  • _form.html.erbのform.label :number, "背番号"のように、日本語がある部分を取る。ja.ymlを利用する。
  • human_attribute_nameは、モデルの属性名をロケールテキストから取り出す。
app/views/members/_form.html.erb
<%= render "shared/errors", obj: @member %>

<table class="attr">
  <tr>
    <th><%= form.label :number %></th>
    <td><%= form.text_field :number, size: 8 %></td>
  </tr>
  <tr>
    <th><%= form.label :name %></th>
    <td><%= form.text_field :name %></td>
  </tr>
  <tr>
    <th><%= form.label :full_name %></th>
    <td><%= form.text_field :full_name %></td>
  </tr>
  <tr>
    <th>性別</th>
    <td>
      <%= form.radio_button :sex, 1 %>
      <%= form.label :sex_1 %>
      <%= form.radio_button :sex, 2 %>
      <%= form.label :sex_2 %>
    </td>
  </tr>
  <tr>
    <th>
      <%= form.label :birthday, for: "member_birthday_li" %>
    </th>
    <td>
      <%= form.date_select :birthday, start_year: 1940, end_year: Time.current.year, use_month_numbers: true %>
    </td>
  </tr>
  <tr>
    <th><%= form.label :email %></th>
    <td><%= form.text_field :email %></td>
  </tr>
  <tr>
    <th><%= Member.human_attribute_name(:administrator) %></th>
    <td>
      <%= form.check_box :administrator %>
      <%= form.label :administrator %>
    </td>
  </tr>
</table>
  • 日本語になったことを確認する。

image.png

エラーメッセージのカスタマイズ

  • 「は不正な値です。」のテキストを変えたければ、ja:→activerecord→errors→messagesの下に、「エラー名:文字列」を記述する。
config/locale/ja.yml(一部)
ja:
  activerecord:
(略)
    errors:
      messages:
        invalid: "の書式が正しくありません。"
  • 新しいエラーメッセージを追加するには、invalid_member_nameのように、新たな文字列で作成する。
config/locale/ja.yml(一部)
ja:
  activerecord:
(略)
    errors:
      messages:
        invalid_member_name: "は半角英数字で入力してください。"
  • 上記で追加したエラーメッセージ:invalid_member_nameを追加する。
app/models/member.rb(一部)
  # nameのバリデート。nil,空,全角/半角空白禁止
  validates :name, presence: true,
    # アルファベットから始まり、英数字のみ
    format: { with: /\A[A-Za-z][A-Za-z0-9]*\z/, allow_blank: true, message: :invalid_member_name },

image.png

YAML

  • yamlファイルの読み込み方法
require "yaml"

animals = YAML.load(File.new("members.yml"))
members.each do |key, val|
  puts "#{val['number']}\t#{val['name']}"
end

国際化機能の使い方

テキスト

  • 日本語用のテキストを用意する
ja:
  messages:
    hello: "こんにちは"
  • ロケールの設定の文字列を取り出す。
s = I18n.t("messages.hello")
  • コントローラやテンプレートの中では、I18nを付けずに、tメソッドが使える。
<%= t("messages.hello") %>
  • テキストの中に値を埋め込む。
ja:
  messages:
    hello: "%{name}こんにちは"
  • 引数に、ハッシュを追加すれば、「Taroさんこんにちは」というテキストになる。
<%= t("messages.hello", name: "Taro") %>

日付と時刻

  • lメソッドの引数には、DateクラスやTimeクラス、ActiveSupport::TimeWithZoneクラスのオブジェクトを渡す。
s = I18n.l(Time.current)
  • コントローラやテンプレートの中では、I18nを付けずに、lメソッドが使える。
<%= l(Time.current) %>
  • lメソッドの第2引数には、formatオプションを指定できる。
  • :longは「2018年05月05日(土) 17時06分56秒 +0900」のような文字列になる。
<%= l(Time.current, format: :long) %>
  • 自分で日付フォーマット作成したい場合、以下のように書式を登録する。
condig/locales/ja.yml(一部)
ja:
  time:
(略)
    formats:
      default:
        medium: "%Y年%m月%d日(%a) %H:%M"
  • formatオプションで指定すれば、上記フォーマットのようになる。
<%= l(Time.current, format: :medium) %>

参考
改訂4版 基礎 Ruby on Rails (IMPRESS KISO SERIES)

5
6
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
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?