ビューヘルパーをコントローラーで呼び出す「view_context」

【結論】

・link_toなどのビューでのみ用いる事が可能な
 ヘルパーメソッドは、view_contextで
 コントローラーに呼び出す事が可能

・ヘルパーメソッドをコントローラーに呼び出せると、
 ヘルパーメソッドで生成されたHTMLを
 そのままDBに保存するなど事が可能になる

【目次】

【本題】

コントローラーにビューヘルパーを呼び出したい

業務でビューヘルパーの「link_to」を、
コントローラーに呼び出したいという場面があったので、
今回はそれをまとめます。

必要になった場面

仕事のコードをそのまま載せる事はできないので、
必要になった場面を、例え話を交えてお伝えします。

例えばブログ投稿サイトで、投稿に「いいね」をすると
下記の様にユーザーに通知が飛ぶ様な機能があるとします。

「○○」さんが、あなたの投稿した「△△」に、いいねをしました

「〇〇」はユーザー名で、
「△△」は自身が投稿した内容のタイトルが表示されます。

この「」内が、それぞれのリンクになっていて、
「〇〇」はユーザーのプロフィール画面へ、
「△△」は投稿した内容の詳細ページへ、
飛ぶ様なコードを書きたいというのが、今回実装したい機能です。

ビューだけでHTMLの生成は困難

ビューでlink_toを用いてリンクを生成しようとすると、
下記の様なコードになると思います。

<div>
 「<%= link_to  @user.name, @user %>」さんが、
 あなたの投稿した「<%= link_to  @post.name, @post %>」に、
 いいねをしました
</div>

但し、通知は「いいね以外」の種類もありますので、
そレラ全てに上記の様なコードを用意すると、非常に冗長になります。

なので、通知内容を下記の形式で直接データベースに保存し、
そのままビューに呼び出しても、リンクが反映される方法を採用しました。

"「<a href="/user/1">ホゲホゲ</a>」さんが、
あなたの投稿した「<a href="/post/1">フガフガ</a>」に、いいねをしました"

その為に今回用いたのが、「view_context」です。

「view_context」について

「view_context」はビュークラスのインスタンスで、
コントローラー上でビューヘルパーを呼び出す為に用いられます。

基本的な記述例は下記の通りです。

view_context.helper

実装例

では先ほどの話に戻って、実装例を紹介します。

まずnotificationsというテーブルを作成して、
通知すべき内容が発生したら、下記の様なレコードを保存するとします。

"「<a href="/user/1">ホゲホゲ</a>」さんが、
あなたの投稿した「<a href="/post/1">フガフガ</a>」に、いいねをしました"

まずはリンクを生成する為のメソッドを「view_context」を用いて定義します。

def create_url(instance)
  view_context.link_to instance.title, instance
end

次にそのメソッドを用いて、userとpostのリンクを生成します。

user_url = create_url(@user)
post_url = create_url(@post)

あとは、それをnotificationsテーブルに保存します

Notification.create!(messege:
t('common.comment_create', user_name: user_url, post_name: post_url))

なお、上記のコードは、
下記の辞書ファイルで定義した文言で保存する様にしています。

ja:
  common:
      comment_create: "「%{@user_name}」さんが、あなたの投稿した「%{@post_name}」に、いいねをしました”

こうすればビューには、下記のコードだけで
リンクを保持した文言を表示させる事が可能になります。

<%= @notification.messege %>