LoginSignup
5
4

More than 5 years have passed since last update.

Rails複合ユニーク制約のバリデーション

Last updated at Posted at 2014-02-28

Goal

* RDBMS側で複合ユニークキーを設定している前提
* Railsのバリデーションによって、Insert SQLを投げる前に重複をチェックする

Preparation

$> uname -a
Linux *** 2.6.32-358.el6.i686 #1 SMP Thu Feb 21 21:50:49 UTC 2013 i686 i686 i386 GNU/Linux
$> cat /etc/issue
CentOS release 6.4 (Final)
Kernel \r on an \m
$> ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [i686-linux]
$> rails -v
Rails 4.0.2

Example

* ユーザが各課題に対して1日1つ日報を出すという設定.
* user(ユーザ)/date(日にち)/subject(課題)でユニークになるようにRDBMS設定している.
* validates_withヘルパでカスタムバリデータをよびだす
* カスタムバリデータはapp/validators以下に定義して、record変数で渡ってくるバリデーション対象でDB selectを実行する
app/model/daily_report.rb
class DailyReport < ActiveRecord::Base
  belongs_to :user
  validates_with DailyReportComplexUniqueValidator
end
app/validators/daily_report_complex_validator.rb
class DailyReportComplexUniqueValidator < ActiveModel::Validator
  def validate(record)
    daily_report = DailyReport.find_by(
      user_id: record[:user_id],
      date: record[:date],
      subject: record[:subject]
    )
    if !daily_report.nil?
      record.errors[:base] << 'user_id, date, subjectのデータがすでに存在しています。'
    end
  end
end

References

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