4
4

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.

validationの条件にI18nを使いたい

Last updated at Posted at 2015-03-19

本当はこうしたほうがいい

Enumを使って定義したほうがスマートだしそっちに寄せられるなら寄せたほうが良さそうです。
参考:
-【Rails】Enum - EnumerizeとActiveRecord::Enum
-RubyでEnumを使いたかったらenumerize
-Enumerizeを数値型カラムで使う

でもI18nに定義してあるので

すでに下記のような感じに定義あったのでこれをどうしてもそのまま利用したかった。

ja.yml
ja:
  master:
    food_category:
      1: 野菜
      2: お肉
      3: お魚
      4: ご飯もの
    5: 麺類
      99: その他   

ここに値のある数値しか保存できないようにvalidationしたい。
その場合は独自validationを定義することになる。

1. validatorをつくる

注:ファイル名がvalidator名になってないと怒られたりする。

lib/validates/food_category_validator.rb

# coding: utf-8
class FoodCategoryValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if !I18n.t("master.food_category").key?(value)
      #エラー文も適当にI18nとしたほうが良さそう     
      record.errors[attribute] << '不正な値です'
    end
  end
end

2. validatorを読み込ませるように設定

config/application.rb

#色々省略
config.autoload_paths += %W(#{config.root}/lib/validates)

3. Modelで使う

app/models/food.rb
class Food < ActiveRecord::Base

  validates :category, food_category: true

  # 失敗1:下記のようにすると、translation missing 扱いになってしまう
  # validates :category, inclusion: { in: I18n.t("master.food_category").keys }

  # 失敗2:これで動くかと思ったけど気のせいだった
  # if: は その条件に合致した場合にvalidationを実施するということ、これでは結局何もしない感じに...。
  # validates :category, if: Proc.new { I18n.t("master.food_category").key?(self.category) }

end

こんな感じで動く

food = Food.new
# =><Food id: nil, category: nil, name: nil, created_at: nil, updated_at: nil>

food.valid?
# => false

food.errors
=> #<ActiveModel::Errors:0x007fbdc2959b88 @base=#<Food id: nil, category: nil, name: nil, created_at: nil, updated_at: nil>, @messages={:category=>["不正な値です"]}>

food.errors.full_messages
# => ["Category 不正な値です"]
# "Category は不正な値です" って I18n つかったらそれっぽくなると思う

独自validationについての参考

4
4
3

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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?