polymorphic associationをつかってPaperclipで画像を複数アップロード
Paperclipの導入
Gemfileの設定
gem "paperclip", "~> 4.1"
上のやつで、generatorが使えない場合はこれで
gem "paperclip", :git => "git://github.com/thoughtbot/paperclip.git"
$ bundle install
前提
- FoodモデルとUserモデルがあって、それぞれimageを複数持つ。
- 最低限必要なことぐらいしか書かないです。
モデルの設定
Foodモデル
class Food < ActiveRecord::Base has_many :images, as: :imageable accepts_nested_attributes_for :images end
User モデル
class User < ActiveRecord::Base has_many :images, as: :imageable accepts_nested_attributes_for :images end
Imageモデル
class Image < ActiveRecord::Base belongs_to :imageable, polymorphic: true has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png" validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/ validates :image, :attachment_presence => true end
マイグレーションの設定
次のコマンドで以下のマイグレーションを作成
rails generate paperclip image image
コマンド使わなくてもいい。
直接画像を扱うImageモデル
class AddAttachmentImageToImages < ActiveRecord::Migration def self.up change_table :images do |t| t.attachment :image end end def self.down drop_attached_file :images, :image end end
画像を持たせたい方のモデル
class CreateFoods < ActiveRecord::Migration def change create_table :foods do |t| t.string :name t.text :description t.timestamps end end end
コントローラーの設定
# /controllers/foods_controller.rb def new @food = Food.new @food.images.build end private def set_food @food = Food.find(params[:id]) end def food_params params.require(:food).permit(:name, :description, images_attributes: [:image]) end
ビューの設定
# /views/foods/show.html.erb <p id="notice"><%= notice %></p> <p> <strong>Name:</strong> <%= @food.name %> </p> <p> <strong>Description:</strong> <%= @food.description %> </p> <p> <strong>Image:</strong> <%= image_tag @food.images.first.image.url(:medium) if @food.images.present? %> </p> <%= link_to 'Edit', edit_food_path(@food) %> | <%= link_to 'Back', foods_path %> | <%= link_to 'Delete', @food, method: :delete, data: { confirm: "you sure?" } %> |
大事なとこ
# ビュ-の書き方 <%= image_tag @food.images.first.image.url(:medium) if @food.images.present? %>
# コントローラーで`new`のとき`build`しておく def new @food = Food.new @food.images.build end
所感
こんな感じでできるはず