【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!メソッド
        保存に失敗すると例外が発生します。
    • attr_protectedメソッド
      attributesメソッドでは更新したくないフィールドを指定します。
      仮にユーザが悪意ある値を送ってきても、指定フィールドは守られます。
  • 削除(コントローラ)
@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(モデル)
        オブジェクトの値に対する検証。
        データベースに書き込まれる値が適切か確認します。
        高レベルな意味的チェックです。
  • 検証ヘルパー
    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;
}