Open4
RailsのForm Objectについて

なぜ使うのか
Railsのフォームは基本的にモデルに依存している。
1つのフォームで複数モデルの操作をしたいときにForm Objectを使うと、処理がすっきりかける。
またログインに関する処理など、特定のフォームでしか行わない処理もForm Objectに書くと良い。

ユースケース
- 1つの記事に複数の画像を保存する処理(記事 has_many 画像 な関係)
- ユーザーのログイン処理

使い方
appディレクトリにformsディレクトリを作る
$ mkdir app/forms
form objectを作る
$ touch app/forms/make_post_form.rb
app/forms/make_post_form.rb
class MakePostForm
include Virtus.model
include ActiveModel::Model # 通常のモデルのようにvalidationなどを使えるようにしたいのでActiveModel::Modelをinclude
extend CarrierWave::Mount # モデル以外でCarrierWaveを使いたいときはこのModuleをextendする
# 使いたい属性を定義
attribute :title, String
attribute :content, String
attribute :image1, String
attribute :image2, String
attribute :image3, String
attribute :image4, String
attribute :image5, String
# 画像アップロード機能なので、uploaderをマウント
mount_uploader :image1, ImageUploader
mount_uploader :image2, ImageUploader
mount_uploader :image3, ImageUploader
mount_uploader :image4, ImageUploader
mount_uploader :image5, ImageUploader
# バリデーション
validates_presence_of %i(
title
content
image1
)
# 保存のしかたを定義
def save_post!
post = Post.new(title: title, content: content).save!
post.images.build(name: image1).save!
post.images.build(name: image2).save! if image2
post.images.build(name: image3).save! if image3
post.images.build(name: image4).save! if image4
post.images.build(name: image5).save! if image5
return post
end
end
controllerで呼び出し
app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
@post_form = MakePostForm.new
end
def create
@post_form = MakePostForm.new(post_params)
if @post_form.save_post!
redirect_to post_url
else
render :new
end
end
private
def post_params
params.require(:make_post_form).permit(
:title, :content, :image1, :image2, :image3, :image4, :image5
)
end
end
viewでformを実装
app/views/posts/new.html.erb
<%= form_with model: @post_form, url: posts_path, local: true do |f| %>
<%= f.text_field :title, placeholder: 'タイトル' %>
<%= f.text_field :content, placeholder: 'コンテンツ' %>
<%= f.file_field :image1 %>
<%= f.file_field :image2 %>
<%= f.file_field :image3 %>
<%= f.file_field :image4 %>
<%= f.file_field :image5 %>
<%= f.submit %>
<% end %>
ログインするとコメントできます