Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby on Rails | Validation | validates_associated

概要

validates_associated

詳細

ActiveRecordで、関連するテーブルとともに正当性をチェックしたい場合に
validates_associatedを利用します、

サンプル

テーブル定義
CREATE TABLE "articles" (
  "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
  "title" varchar(255), 
  "text" text, 
  "created_at" datetime, 
  "updated_at" datetime
);
CREATE TABLE "comments" (
  "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
  "commenter" varchar(255), "body" 
  text, "article_id" 
  integer, "created_at" datetime, 
  "updated_at" datetime
);
Validation
class Article < ActiveRecord::Base
  validates :title, presence: true, length: { minimum: 5 }
end
class Comment < ActiveRecord::Base
  belongs_to :article
  validates_associated :article
end
試行

rails console(pry)で試行します。
save(validate: false)を利用して、不正なarticleを保存した後に、
commentから該当articleに関連づけます。

[1] pry(main)> a = Article.new
=> #<Article id: nil, title: nil, text: nil, created_at: nil, updated_at: nil>
[2] pry(main)> a.save(validate: false)
=> true
[3] pry(main)> a
=> #<Article id: 20, title: nil, text: nil, created_at: "2014-06-30 23:47:10", updated_at: "2014-06-30 23:47:10">
[4] pry(main)> c = Comment.new
=> #<Comment id: nil, commenter: nil, body: nil, article_id: nil, created_at: nil, updated_at: nil>
[5] pry(main)> c.valid?
=> true
[6] pry(main)> c.article_id = 20
=> 20
[7] pry(main)> c.valid?
  Article Load (1.0ms)  SELECT  "articles".* FROM "articles"  WHERE "articles"."id" = ? LIMIT 1  [["id", 20]]
=> false
[8] pry(main)> c.errors.messages
=> {:article=>["is invalid"]}