shou2017.com
JP / EN

Rails5で画像をアップロードする

Sat Feb 3, 2018
Sat Aug 10, 2024

carrierwaveを使って画像をアップロードします。

とりあえず、今回はただのサンプルなのでscaffoldを使ってitemを作ります。後からimage:stringを追加するので、ここで作ってしまってもいい。

$ rails g scaffold item description:text

gemfileに追記後、bundle install

gem 'carrierwave'

itemsテーブルに画像のカラムを追加

$ rails g migration AddImageToItems image:string
$ rake db:migrate

carrierwaveの設定

CarrierWaveでは、uploaderというプログラムファイルを作成することで画像アップロード機能を使うことができるようになります。ここではimageで作ったのでカラムの名前もこれに合わせます。名前自体は任意です。

$ rails g uploader image

app/uploaders/image_uploader.rbが生成されていればokです。

次にapp/models/item.rbに以下のコードを追記します。

class Item < ActiveRecord::Base
  mount_uploader :image, ImageUploader
end

viewとcontrollerに、画像をアップロードし保存するためのコードを追加します。itemの新規作成時にファイルを選択し、一緒に投稿でき且つ、itemの保存の際にurlをテーブルに保存できるようにします。

app/views/items/_form.html.erbを以下のようにします。これで、画像ファイルを選択して添付できるようになります。

<%= form_for(@item) do |f| %>
  <% if @item.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@item.errors.count, "error") %> prohibited this item from being saved:</h2>

      <ul>
      <% @item.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end  %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
    <%= f.file_field :image %> ←これを追記した。
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end  %>

次はコントローラの設定です。

items_controllerを以下のようにします。ストロングパラメーターで許可するキーにimageを追加します。

private
  # Use callbacks to share common setup or constraints between actions.
  def set_item
    @item = Item.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def item_params
    params.require(:item).permit(:description, :image)
  end
end

見た目を整える

一覧ページで見られるようにします。app/views/items/index.html.erbを以下のようします。

<p id="notice"><%= notice %></p>

<h1>Listing Items</h1>

<table>
  <thead>
    <tr>
      <th>Description</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @items.each do |item| %>
      <tr>
        <td><%= item.description %></td>
        <td><%= image_tag item.image.url %></td> ←これを追加
        <td><%= link_to 'Show', item %></td>
        <td><%= link_to 'Edit', edit_item_path(item) %></td>
        <td><%= link_to 'Destroy', item, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Item', new_item_path %>

これで終了。

但し、NameError uninitialized-constantがでる場合があります。僕も出ました。

色々、ググりましたが、springを再起動で解決しました。config/application.rbとかをイジルことで解決した人もいるみたいですが、再起動で治るなら、そっちの方がいい。

springとは、アプリケーションローダーのことです。

statusの確認。

$ spring status

停止

$ spring stops

起動

$ rails c
See Also