Formオブジェクトとは
モデルとフォームの責務を切り分けられる事で、単体のモデルに依存しない場合や、フォーム専用の特別な処理をモデルに書きたくない場合に用いる。
Railsのフォームは基本的にモデルに依存する。
例えば1つのフォーム送信で複数のモデルの更新をしたい場合バリデーションの責務が曖昧なものとなり、可読性も低下する
ため、責務を明確にするとことで使う。
1つのフォームで複数モデルの操作をしたいときにForm Object
を使うと、処理がすっきりかける。またログインに関する処理など、特定のフォームでしか行わない処理もForm Object
に書くと良い。
メリット
・ActiveRecord
と同じバリデーションを使うことができる
・Form Object
にパラメーターをそのまま渡すことができるためエラーメッセージを戻す処理が書きやすい
・責務がモデルとは言い切れないビジネスロジックをcontroller/view
から切り離せる
ユースケース
サインアップ処理
ユーザの作成と他ユーザのフォローを同時に行うなど、複数のActiveRecordモデルを作成
するとき。
複数のタグを作成
複数の子レコードを作成するとき。accepts_nested_attributes_for
を使うような場面だが使いたくないとき。
ブログの検索フォーム
ActiveRecordモデルを使用しない
場合。
使い方
1.formsディレクトリ、利用したいフォームファイルの作成
2.コントローラーに記載
1.formsディレクトリ、利用したいフォームファイルの作成
app/forms
ディレクトリを作成し、その中に利用したいフォームのFormオブジェクトを作成する。
$ mkdir app/forms
$ touch app/forms/sample_form.rb
作成したファイルに、バリデーションや使用するメソッドを記述していく。
class SampleForm
include ActiveModel::Model
#↑通常のモデルのようにvalidationなどを使えるようにする
include ActiveModel::Attributes
#↑ActiveRecordのカラムのような属性を加えられるようにする
attribute :first_name, :string
attribute :last_name, :string
attribute :email, :string
attribute :body, :string
validates :first_name, presence: true
validates :last_name, presence: true
validates :email, presence: true
validates :body, presence: true
def save
処理
end
end
2.コントローラーに記載
class SamplesController < ApplicationController
def new
@sample = SampleForm.new
end
def create
@sample = SampleForm.new(sample_params)
if @sample.save
redirect_to :samples, notice: 'サンプル情報を作成しました。'
else
render :new
end
end
private
def sample_params
params.require(:sample).permit(:first_name, :last_name, :email, :body)
end
end