【Rails:4】MVCの連携
フォームとモデル
- フォームとモデルの連携
レコード(モデル)⇔コントローラ⇔フォーム(ビュー)
- フォームの作成(ビュー)
<% form_for :mdlname, @objname, :url => {:action => actname, :id => @objname}, :html => {:class => 'formname'} do |form| %> <!-- 各フォームを設置 --> <% end %>
-
- テキストフォーム(単数行)
<%= form.text_field :clmname, :size => 20 %> <!-- 一般的なテキストフォーム --> <%= form.password_field :clmname :size => 10 %> <!-- パスワード用テキストフォーム --> <%= form.hidden_field :clmname %> <!-- ユーザには見えないテキストフォーム --> <!-- フォームへの入力は必要ない値を渡すのに利用 -->
-
- テキストフォーム(複数行)
<%= form.text_area :clmname, :cols => 50, :rows => 30 %>
<%= form.check_box :clmname, {html_options}, val_if_on, val_if_off %> <!-- val_if_on/off を省略した場合、デフォルト値は 1/0 -->
<%= form.radio_button :clmname, val_if_on %>
-
- プルダウンリスト
<%= form.select :clmname, array_of_listitems %> <!-- 一般的なプルダウンリスト --> <%= form.date_select :clmname, :start_year => 2000, :end_year => Time.now.year, :use_month_numbers => true/false %> <!-- 日時の選択用プルダウンリスト --> <!-- :use_month_numbers が true なら、月の表記が数字になる -->
-
- アップロードフォーム
<%= form.file_field :clmname %> <!-- form_forメソッドの:htmlオプションに以下が必要 --> <!-- :html => {:multipart => true} -->
-
- 送信ボタン
<%= submit_tag btn_name %>
レコードの作成・更新・削除
- 新規作成(コントローラ)
@objname = MdlName.new(params[:mdlname]) # params[:mdlname] == {:clmname1 => val1, # :clmname2 => val2, # …} @objname.save # params[:mdlname][:clmname1]などとすれば、フィールド毎の値を扱うことも可能
@objname = MdlName.new @objname.attributes = params[:mdlname] @objname.save
@objname = MdlName.create(params[:mdlname])
- 更新(コントローラ)
@objname = MdlName.find(id) @objname.attributes = params[:mdlname] @objname.save
@objname = MdlName.find(id) @objname.update_attributes = params[:mdlname]
@objname = MdlName.update(id, params[:mdlname])
-
- save/save!メソッド
- saveメソッド
保存に成功するとtrue、失敗するとfalseを返します。
検証に弾かれた場合、保存は行わずにfalseを返します。
保存時にデータベースにエラーが発生した場合、例外が発生します。 - save!メソッド
保存に失敗すると例外が発生します。
- saveメソッド
- save/save!メソッド
-
- attr_protectedメソッド
attributesメソッドでは更新したくないフィールドを指定します。
仮にユーザが悪意ある値を送ってきても、指定フィールドは守られます。
- attr_protectedメソッド
- 削除(コントローラ)
@objname = MdlName.find(id) @objname.destroy
MdlName.destroy(id)
MdlName.destroy([id1, id2, id3, ...]) # 複数のレコードを削除 MdlName.destroy_all(["clmname1 = ?", "hoge"]) # clmname1フィールドが"hoge"のレコードをすべて削除
-
- 論理削除
destroyメソッドは、物理的にテーブルからレコードを削除してしまいます。
しかし、削除したレコードが後で必要になる等の可能性を踏まえ、物理削除ではなく論理削除する場合があります。
論理削除をするには、論理値型や整数値型のフィールドを設け、削除状態のときの値を決めます。
findメソッド等を使用するときは、レコードがユーザから見えないよう、削除状態のレコードを除くような条件を指定します。
- 論理削除
検証
- validateメソッド(モデル)
記述した条件に従って、レコードの作成・削除が行われる際、値が適切かどうか検証します。
値が不適切な場合、errors.addメソッドを使用して、エラーを記録することができます。
作成/更新時のみ検証したい場合は、validate_on_create/validate_on_updateメソッドを使用します。
-
- verifyとvalidateの違い
- verify(コントローラ)
HTTPリクエストに対する検証。
ユーザのアプリケーションの利用の仕方が適切か確認します。
低レベルな形式的チェックです。 - validate(モデル)
オブジェクトの値に対する検証。
データベースに書き込まれる値が適切か確認します。
高レベルな意味的チェックです。
- verify(コントローラ)
- verifyとvalidateの違い
- 検証ヘルパー
validateメソッドで条件分岐を書かなくても、基本的な検証を行ってくれます。
主なヘルパー | オプション | 検証内容 | エラーメッセージ |
---|---|---|---|
validates_length_of | :in, :is, :minimum, :maximum | 長さは適切か? :in ⇒ この範囲内か? :is ⇒ これと同値か? :miinimum ⇒ これ以上か? :maximum ⇒ これ以下か? |
:wrong_length ⇒ :isを満たさない場合 :too_long ⇒ :minimumを満たさない場合 :too_short ⇒ :maximumを満たさない場合 |
validates_numericallity_of | :only_intege | 数値か? :only_integer ⇒ true(整数値)か? |
|
validates_presence_of | 空でないか? | ||
validates_uniqueness_of | :case_sensitive :scope |
他のレコードと重複しないか? :case_sensitive ⇒ true(大文字・小文字も含めて重複しない)か? :scope ⇒ このフィールドも重複しないか? |
-
- :ifオプション
:if => Proc.new{|objname| 条件} # 条件がtrueの場合のみ検証を行う
- エラーメッセージ(ビュー)
<%= error_messages_for(:mdlname) %> <!-- テーブルに関するエラーメッセージをすべて表示 --> <%= error_message_on(:mdlname, :clmname) %> <%= @objname.errors.on(:clmname) %> <!-- フィールドごとのエラーメッセージを表示 -->
-
- フォームとエラー表示
エラーしたフィールドは、<div class="fieldWithErrors"> というdiv要素で囲まれます。
CSSで以下のように設定すれば、エラーしたフィールドの背景色が赤色になって目立ちます。
- フォームとエラー表示
div.fieldWithErrors{ padding: 2px; background-color: red; }