ActiveModelを使ってDBと関係ないFormの構築してみた

こんにちは!kossyです!




さて、今回はActiveModelを使ったフォームの構築についてブログに残してみたいと思います。



そもそもActiveModelって??

DBと関係ないFormを構築できるスグレモノです。
Active Recordを使った時と同じ振る舞いを実現できます。

Formに関して責務の分離を行うことができるので、
ばらつきがちなロジックをまとめられたり、検索周りの機能の共通化ができたりします。





実装方法

例として、運営に問い合わせを行うようなフォームを構築してみます。

app/forms/inquiryforms.rb

class InquiryForm
  include ActiveModel::Model
  include ActiveModel::Attributes
  attr_accessor :subject, :content, :accepted

  attribute :accepted, :boolean, default: false

  validates :subject, presence: true, length: { maximum: 100 }
  validates :content, presence: true

  def save
    return false if invalid?
    ActionMailer.inquiry_form(subject, content).deliver_later
    true
  end

end




app/controllers/inquiries_controller.rb

class InquiriesController < ApplicationController

  def new
    @inquiry_form = InquiryForm.new
  end

  def create
    @inquiry_form = InquiryForm.new(inquiry_form_params)
    if @inquiry_form.save
      redirect_to home_path, notice: '問い合わせを送信しました。'
    else
      render :new
    end
  end

  private

  def inquiry_form_params
    params.require(:inquiry_form).permit(:subject, :content, :accepted)
  end

end

include ActiveModel::ModelでActiveModelの機能を利用できるようになります。
attr_accessorで使用する属性を定義します。

include ActiveModel::Attributesは属性のキャストを簡単に行えるようになる機能です。
acceptedはrailsのビューヘルパーであるcheck_boxを介して値が送られてくることを想定している(Stringでくる)ため、
booleanにキャストしたいので定義しています。

saveメソッドはバリデーションに引っかかっていないか検証し、値が正しければメールを送信しています。


応用すれば商品検索フォームや投稿フォームにも使えそうです。



参考にさせていただいたサイト
ActiveModel::Modelで簡単に検索機能追加 - Qiita
ActiveModelのベストプラクティスを考える - Lチカ開発ブログ
form objectを使ってみよう - メドピア開発者ブログ
ActiveModel::Attributes が最高すぎるんだよな。 - Qiita
ActiveModel::Model で簡単に ActiveModel の機能を利用する - happy lie, happy life