【gem：Refileの使い方】Railsでの画像投稿機能の実装方法

プログラミング初心者に向けて、Ruby on Railsで画像投稿機能を実装する方法についてご紹介します。今回は「Refile」というgemを使って、[以前解説したRuby on Railsを使って作成したシンプルなToDoアプリ](https://taishi-official.com/2020/04/25/433/)を例に実装していきます。

## 【gem】Refileとは
「Refile」はRuby on Railsのgemで、<b>ファイルアップロードを簡単に実装するためのライブラリ</b>です。Refileを使うことで、画像のアップロードやリサイズ、クロップなどが簡単にできます。

またRefileでアップロードされた画像はRailsのActiveRecordを使用して、データベースに画像を保存することができます。GitHub上でオープンソースとして公開されています。

[>> 「Refile」のGitHub](https://github.com/refile/refile)

## 【gem】Refileを使って画像投稿機能の実装
### Gemfileに追記する
gemを使うには、使いたいgem名を「Gemfile」内に追記する必要があります。<b>Gemfileは、Railsで使うgemを管理するファイル</b>です。gemの名前を追記しておくと、そのgemをRubyから利用できるようになります。

さらに今回は、サイズ調整など画像加工を行うgemの<b>MiniMagick</b>も追加することにします。

それでは実際に、今回のgemの記述をGemfileに追加していきましょう。Gemfileの一番下に書いてください。

~~~ ruby:Gemfile
...
gem "refile", require: "refile/rails", github: 'manfe/refile'
gem "refile-mini_magick"
~~~

Gemfileに新たに追加したときは、bundle installコマンドも実行する必要があります。bundle installは、Gemfileに記述されたgemをインストールするコマンドです。

~~~
$ bundle install
~~~

### image_idカラムを追加する
画像を保存するためのカラムを追加します。カラム名は、「image_id」のようにidを付けて設定します。

カラムに追加するマイグレーションファイルを作成し、データベースを変更します。<b>データ型は文字列型</b>にします。

~~~
$ rails g migration AddImageIdToTodos image_id:string
~~~

マイグレーションファイルを作成できたので、実行してデータベースに反映させます。

~~~
$ rails db:migrate
~~~

### attachmentメソッドを追加する
Refileを使うには、attachmentメソッドをモデルに追加する必要があります。Todoモデルに以下のように追加します。

~~~ ruby:app/models/todo.rb
class Todo < ApplicationRecord
    attachment :image
end
~~~

カラム名はimage_idですが、ここでは<b>_idをつけない</b>ので注意してください。

### Strong Parametersを追加する
TodoControllerのStrong Parametersに、imageカラムを追加します。

~~~ ruby:app/controllers/todos_controller.rb

class TodosController < ApplicationController

...  

  private
    def todo_params
    params.require(:todo).permit(:title, :image)
  end

end
~~~

### 画像投稿フォームを追加する
投稿フォームに、画像投稿フォームを追加します。

~~~ ruby:app/views/todos/new.html.erb

<h1>新規投稿</h1>

<%= form_for(@todo) do |f| %>

  <h4>タイトル</h4>
  <%= f.text_field :title %>
  <h4>画像</h4>
  <%= f.attachment_field :image %>
  <%= f.submit '投稿' %>

<% end %>

~~~

### attachment_image_tagを埋め込む
一覧画面と詳細画面に投稿した画像を表示します。
該当箇所にattachment_image_tagを埋め込みます。以下のように記述します。画像の幅を:fillで指定し、高さをpxで指定しています。また、表示する画像の拡張子をformatで指定しています。

 

#### indexページに記述する
index.html.erbファイルには、以下のように記述します。

~~~ ruby:app/views/todos/index.html.erb

<h1>投稿一覧</h1>
  <% @lists.each do |list| %>
    <p>タイトル</p>
    <span><%= list.title %></span>
    <p>画像</p>
    <%= attachment_image_tag todo, :image, :fill, 100, 100, format: 'jpeg' %>
 <% end %>

~~~

#### showページに記述する
show.html.erbファイルには、以下のように記述します。

~~~ ruby:app/views/todos/show.html.erb

<h2>タイトル</h2>
<p><%= @todo.title %></p>

<h2>画像</h2>
<%= attachment_image_tag @list, :image, :fill, 300, 300, format: 'jpeg' %>

<%= link_to "編集", edit_todo_path(@todo.id) %>

~~~

これで、画像投稿の実装は完了です。新規投稿画面にアクセスし、画像投稿してみましょう。index画面とshow画面に画像が表示されるようになっています。

## まとめ
以上が、Refileを使った画像投稿機能の実装方法についてでした。SNSなどで画像投稿機能は必須といっても過言ではない機能です。この記事を参考にして、実装にチャレンジしてみてください！

### おまけ

https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/learning-programming/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup: