スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Merb]DataMapperのvalidation

前回に引き続きDataMapperについてです。
今回はvalidation関係を探ってみようと思います。

Modelを編集します。

vi app/models/entry.rb

class Entry
 include DataMapper::Resource

 validates_present :title, :content

 property :id, Serial

 property :title, String, :unique => true
 property :content, String

 has n, :comments
end



実行してみます。

rake db:automigrate
merb -i
entry = Entry.new
entry.title = "タイトル1"
entry.save



失敗しました。
validates_presentで指定されたフィールドは値を保存しないと怒られるようです。

entry.content = "内容1"
entry.save



次に別レコードで同じtitleを登録しようとします。

entry = Entry.new
entry.title = "タイトル1"
entry.content = "内容2"
entry.save



失敗しました。
unique指定しているため、ちゃんとチェックしてくれるようです。

事前に保存可能かどうかを調べるには・・

entry.valid?



でいけるみたいです。

後は独自のチェックをしたい場合は、Modelにチェックメソッドを定義したり
valid?をオーバーライドするとかでしょうか。

例えばcontentが10バイト未満をエラーにするとして・・

vi app/models/entry.rb

class Entry
 include DataMapper::Resource

 validates_present :title, :content

 property :id, Serial

 property :title, String, :unique => true
 property :content, String

 has n, :comments

 def vaiid?(context = :default)
  if !super(context)
   return false
  end
  if @content.length < 10
   return false
  end
  true
 end
end



試してみます。

merb -i
entry.title = "abcd"
entry.content = "123456789"
entry.valid?
=> false

entry.content = "1234567890"
entry.valid?
=> true



関連づけているModelまでチェックしてくれるのか試してみます。
commentのcontentを必須とします。

vi app/models/comment.rb

class Comment
 include DataMapper::Resource

 validates_present :content

 property :id, Serial

 property :entry_id, Integer
 property :content, String

 belongs_to :entry
end



実行します。

merb -i
entry = Entry.new
entry.title = "abcd"
entry.content = "1234567890"
entry.valid?
=> true

entry.comments.push(Comment.new)
entry.valid?
=> true



entry.valid?は通過しました。
どうやら関連づいたModelのチェックまではしないようです。

entry.comments[0].valid?
=> false



直接comment.valid?を呼ぶとfalseが返されます。
保存しようとするとどうなるのか。

entry.save

~ SELECT "id" FROM "entries" WHERE ("title" = 'abcd') ORDER BY "id" LIMIT 1
~ INSERT INTO "entries" ("content", "title") VALUES ('1234567890', 'abcd')
~ SELECT "id", "entry_id", "content" FROM "comments" WHERE ("entry_id" IN (3)) ORDER BY "id"
=> true



commentテーブルへの追加は行われませんでした。
ちゃんとcomment.contentにデータを入れます。

entry.comments[0].content = "comment"
entry.save

~ SELECT "id" FROM "entries" WHERE ("title" = 'abcd') ORDER BY "id" LIMIT 1
~ INSERT INTO "comments" ("entry_id", "content") VALUES (3, 'comment')
~ SELECT "id", "entry_id", "content" FROM "comments" WHERE ("entry_id" IN (3)) ORDER BY "id"
=> true



今度はcommentテーブルにデータを追加されました。

エラーメッセージは以下の方法で取得できるようです。

entry = Entry.new
entry.title = "abcd"
entry.valid?
=> false
entry.errors.full_messages
=> ["Title is already taken", "Content must not be blank"]



エラーコード的なものも取得できたら良いなと思ったのですが
よくわからなかったです。

コメントの投稿

非公開コメント

プロフィール

jou4

Author:jou4
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。