RailsのForm ClassとForm builder


Ruby on RailsのFormが単体のモデルに依存しないような場合や、フォーム専用の特別な処理をモデルに書くべきではないといった場合はForm Class(Form Object)を作る手法があります。合わせてオリジナルのフォームビルダを作成してViewへのロジックの記述量を減らす手法を紹介します。

🚕 Form Classのメリット

  • ビジネスロジックをController/Viewから切り離すことができた
  • ValidationなどをModelと同じように実施でき、エラーもフォームに渡すことができる

🗻 ユーザー登録フォーム

一般的なユーザー登録フォームで、バリデーション => ユーザー登録 => メール通知 => ロギングなどを行うサンプルを紹介します。
まずFormオブジェクトのサンプルです。include ActiveModel::Modelをincludeすることでバリデーションなどを簡単に記述できます。

# app/models/form/registration.rb
class Form::Registration
include ActiveModel::Model
attr_accessor :first_name, :last_name, :email, :terms_of_service
validates :email, presence: true, email: true
validates :first_name, presence: true
validates :last_name, presence: true
validates :terms_of_service, acceptance: true
def register
if valid?
# バリデーションを通過した後の処理を記述
# - Userの作成
# - メール通知
# -ロギング...
end
end
private
def create_user
# ...
end
end

Controller側には通常のモデルと同じように扱います。

# app/controllers/registration_controller.rb
class RegistrationController < ApplicationController
def new
@registration = Form::Registration.new
end
def create
@registration = Form::Registration.new(registration_params)
if @registration.register
redirect_to registration_path(@registration)
else
render :new
end
end
private
def registration_params
# ...
end
end

View側も通常のモデルと同じようにform_forメソッドを使います。

<!-- app/views/registration/new.html.erb -->
<%= form_for @registration do |f| %>
<%= f.label :first_name, 'First Name' %>:
<%= f.text_field :first_name %>
...
<%= f.submit %>
<% end %>

routes.rbにも通常と同じ記述ができます。

resources :registrations, only: %i[new create]

😼 フォームビルダのカスタマイズ

form_forによって生成されるオブジェクトはFormBuilderのインスタンスです。
FormBuilderのサブクラスを作成して、ヘルパーの追加を簡単に行うことができます。
View側でのFormBuilderの指定方法は次のとおりです。

<%= form_for @person, builder: SampleFormBuilder do |f| %>
<%= f.text_field :first_name %>
<% end %>

SampleFormBuilderは次のように定義します。

class SampleFormBuilder < ActionView::Helpers::FormBuilder
def text_field(attribute, option = {})
label(attribute) + super
end
end

🐝 参考リンク

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍