Railsでモデルなしの簡易的なメッセージ送信機能をつけます。
メッセージ送信機能といっても幅広いため、今回はモデルなしでパラメーターのみで情報を取得し、その情報をメールで管理者へ送信する機能とします。
※本記事では、リクエストボックスとします。
・メール送信の設定済み
メイラーを作成
rails g mailer RequestFormMailer
上記にて/app/mailers/request_form_mailer.rb というファイルができます。
class RequestFormMailer < ApplicationMailer
def request_form_to_admin(contents)
@contents = contents
mail(
from: '"BOOK TECH株式会社" <support@book-tech.com>',
to: 'contact-ml@book-tech.com',
subject: '【BOOK TECH】リクエストを受け付けました。'
)
end
end
/app/views/request_form_mailer のディレクトリへ request_form_to_admin.text.erb を作成してadminへメール送付する際のテンプレートを作成します。
<管理者向け>
下記のリクエストを受け付けました。
内容
<%= @contents %>
以上でメールを送信する準備が整いました。
コントローラを作成
rails g controller request_forms
class RequestFormsController < ApplicationController
def create
RequestFormMailer.request_form_to_admin(params[:request_contents]).deliver_later
end
end
ルートを作成
Rails.application.routes.draw do
# 省略
post 'request_forms' => 'request_forms#create'
# 省略
end
念の為ルートが作成されているかrails routesで確認してみます。
rails routes
Prefix Verb URI Pattern Controller#Action
request_forms POST /request_forms(.:format) request_forms#create
問題なく作成されていました。
Viewを編集
リクエストボックスを実装するViewファイルへ下記を追加します。
<!--今回は非同期通信で実装-->
<div id="request-contents-box">
<%= form_with(url: request_forms_path, method: :post ) do |f| %>
<%= f.text_area :request_contents, type: 'text', class: '' %>
<%= f.submit "送信", class: '' %>
<% end %>
</div>
<!--非同期通信をしない場合は、local: trueを追加すればOKです。-->
<%= form_with(url: request_forms_path, method: :post, local: true) do |f| %>
送信ボタンを押した後に、<div id=”request-contents-box”>~</div> で囲った箇所を非同期で書き換えたいため、request_formsコントローラーのcreateアクションのViewとして、/app/views/request_forms ディレクトリへ create.js.erb を作成します。
$("#request-contents-box").html('送信完了しました');
これで送信ボタンを押すと、「送信完了しました」と表示されるようになります。
書き換える内容をテキストではなく、部分テンプレートを使用する場合は下記の記述にすればOKです。
$("#request-contents-box").html('<%= escape_javascript(render("****/***")) %>');
<!--下記の記述でも同様の結果になります-->
$("#request-contents-box").html('<%= j(render("****/***")) %>');
空送信を許可しない設定にする
これまでの実装の場合だと、空送信(paramsがnilの状態)でもadminへメールを送ってしまう&送信完了しました、と表示されます。
空送信時は無効にするために、まず <div id=”request-contents-box”>~</div> の中身を部分テンプレートにします。
<div id="request-contents-box">
<%= render 'layouts/request_form' %>
</div>
/app/views/layouts ディレクトリ配下に _request_form.html.erb を作成します。
<%= form_with(url: request_forms_path, method: :post ) do |f| %>
<%= f.text_area :request_contents, type: 'text', class: '' %>
<%= f.submit "送信", class: 'btn' %>
<% end %>
そしてcreateアクションにおいては、params[:request_contents]があるときだけMailerを起動するように変更します。
class RequestFormsController < ApplicationController
def create
if params[:request_contents].present?
RequestFormMailer.request_form_to_admin(params[:request_contents]).deliver_later
end
end
end
createアクションのviewは、params[:request_contents]がある場合は送信完了した旨を表示させ、ない場合は layouts/request_form を表示させます。
<% if params[:request_contents].present? %>
$("#request-contents-box").html('送信完了しました');
<% else %>
$("#request-contents-box").html('<%= escape_javascript(render("layouts/request_form")) %>');
<% end %>
以上で空送信をしても、見た目はなにも変わらず、文字を打ち込んだ状態であれば送信できるようになります。
サービスに組み込んだ際の動き
今までの流れをベースに、サービスに組み込む際はニックネーム欄を追加したり、CSSやjQueryでカスタマイズして実装しました。
参考になれば幸いです。