# FormでもらったデータをDBに保存しないActiveModel::Model
# ActiveModel::Model
みなさん、ActiveModelって知ってますか?
例えば、Formで受け取ったデータをDBに保存せずに、何かの実装したいときにメチェメチャ便利です!
今回は、Formで{ query: { :name, :email } }を受け取り、DBには保存せずにActionMailerを使ってMailを流す場合を考える。
# ActiveModel::Modelを使わない場合
app/controllers/queries_controller.rb
class QueriesController < ApplicationController
def new
end
def create
if params[:name].present? && params[:email].present? # if文の条件分岐のvalidationは好ましくない
ContactMailer.post_email(params[:name], params[:email]).deliver
else
# このelse文の中身のvalidationは綺麗じゃない
@error_messages = []
@error_messages << 'タイトルを入力してください' if params[:name].blank?
@error_messages << '本文を入力してください' if params[:email].blank?
render :new
end
end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
app/views/queries/new.html.erb
<%= form_with url: queries_path, local: true do %>
<% @error_messages && @error_messages.each do |message| %>
<%= message %>
<% end %>
<%= label_tag :name %>
<%= text_field_tag :title, params[:name] %>
<%= label_tag :email %>
<%= text_area_tag :body, params[:email] %>
<%= submit_tag %>
<% end %>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Queryのテーブルがない場合、当然自分でModelを作ろうなんて普通は思わないですよね? また、以上のような場合はControllerの役割を超えすぎてるし、validationが美しくない!
そんなときに便利なのが、ActiveModel::Model!
# ActiModel::Modelを使う場合
Viewは以上と同じなので、割愛。
app/controllers/queries_controller.rb
class QueriesController < ApplicationController
def new
end
def create
@query = Query.new(query_params)
if @query.save
redirect_to home_path, notice: 'フィードバックを送信しました'
else
@query.errors.full_messages
end
end
private
def query_params
params.require(:query).permit(
:name,
:email
)
end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
app/models/query.rb
require "active_model" # これを忘れずに
class Query # DBに保存しないため、ActiveRecoredは継承しない!
include ActiveModel::Model
attr_accessor :name, :email
validates :name, :email, presence: true
def save
return false unless valid?
ContactMailer.post_email(params[:name], params[:email]).deliver
true
end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
これで、ControllerはController自身の役割を超えずに、またvalidationもきれいに書くことができる