LoginSignup
3
4

More than 3 years have passed since last update.

Rails の Carrierwave を使用した画像複数アップロード機能

Last updated at Posted at 2021-01-13

備忘録のため記述しています。

Carrierwave という gem の導入

carrierwaveuploader/carrierwave

Gemfile に以下を記述

gem "carrierwave", "~> 2.0"

終わったらターミナルにて bi

bundle install

Uploader の作成

bundle exec rails g uploader Images

下記が作成される。

images_uploader.rb

アップロードされるファイルの設定を色々弄れるけど今回は見送り。

MVC 設定

Post モデルに対して Memory というモデルで画像登録をできるようにしている

Model

Post

post.rb
class Post < ApplicationRecord
  has_many :memories
  accepts_nested_attributes_for :memories, allow_destroy: true
  validates :title, presence: true
end

accepts_nested_attributes_for :memories の設定で posts_controller 上で memories を登録できるようにしている。

Memory

memory.rb
class Memory < ApplicationRecord
  belongs_to :post
  mount_uploader :image, ImagesUploader
end

mount_uploader は carrierwave の設定。これで簡単にアップロードできるようになる。

Controller

posts_controller.rb

posts_controller.rb
class PostsController < ApplicationController


  def new
    @post = Post.new
        # @post.memories.build とすることで post に紐づいた memories を保存する準備が整う
    @post_memory = @post.memories.build
  end

  def create
    post = Post.new(post_params)
    if post.save!
        # 以下は memories に保存する処理。 each 文で複数の画像を保存可能。
      params[:memories][:image].each do |image|
        post.memories.create(image: image, post_id: post.id)
      end
    end
    redirect_to root_path
  end

  private

    def post_params
      params.require(:post).permit(:title, memories_attributes: [:image]).merge(user_id: current_user.id)
    end
end

View

new.html.erb

<%= form_for @post, local: true,  html: {class: "form_area"} do |f| %>
        <div class="form_area__field">
          <%= f.text_area :title, id: "post_text", placeholder: "投稿内容を入力", rows: 10%>

          <div class="form_area__image_field">
            <%= f.fields_for :memories do |m| %>
              <%= m.label :image, "画像" %>
              <%= m.file_field :image, multiple: true, name: "memories[image][]" %>
              <%= hidden_field :memories, :post_id, value: @post.id %>
            <% end %>
          </div>

          <div class="form_area__hidden_field">
            <%= hidden_field :post, :user_id, value: current_user.id %>
          </div>

          <div class="form_area__action">
            <%= f.submit "投稿", class: "form_area__action__btn" %>
          </div>

        </div>
      <% end %>

fields_for で1回の投稿で複数のクラスを保存できる。

multiple: true で複数の画像を投稿できるように設定している。

表示するには?


<% @post.memories.each do |m|%>
     <%= image_tag m.image.url %>
<% end %>

上記で表示できる。

画像を追加するには? (2021年1月16日追記)

既に画像つきで投稿されている記事に対して画像を追加する機能を実装しました。
結果としてはすごくシンプルですが、どう実装したものかよくわからず苦戦しました。

機能

  • 記事の内容が変更されたら記事のみ変更
  • それ以外の場合画像が追加される

Controller


def update

    post = Post.find(params[:id])
    # 更新前の記事と params として渡された記事を比較している
    if post.title != params[:post][:title]

      post.update!(post_params)

    else
      post.save!

      params[:memories][:image].each do |image|
        post.memories.create(image: image, post_id: post.id)
      end
    end

    redirect_to root_path
  end

選択した画像を編集できた方がより良いと思いますが、こちらの機能はまた今度。。。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4