質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

424閲覧

rails carrierwaveでネストされたモデルに複数の画像を投稿したい

hiro610

総合スコア12

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2018/12/31 10:22

###前提
productモデルとimageモデルは1対多の関係。

productrb

1 has_many :images, dependent: :destroy 2 accepts_nested_attributes_for :images, limit: 4 3 accepts_nested_attributes_for :brand

imagerb

1 belongs_to :product, optional: true 2 mount_uploader :image, ImageUploader

###実現したい事
1つの商品(product)を投稿する特imageモデルに商品に紐づく画像を4枚設定して投稿できるようにしたいです。

###コード

productcontroller

1class ProductsController < ApplicationController 2 before_action :product_new, only:[:new] 3 before_action :product_info, only: [:show, :item_show, :destroy] 4 5 def new 6 @images = @product.images.build 7 end 8 9 def create 10 @product = Product.new(product_params) 11 @product.brand = Brand.find_or_create_by(name: @product.brand.name) if @product.brand.name 12 13 respond_to do |format| 14 if @product.save 15 params[:images][:image].each do |i| 16 binding.pry 17 @product.images.create(product_id: @product.id, image: i) 18 end 19 format.html { redirect_to root_path} 20 # redirect_to root_path 21 else 22 render action: :new 23 end 24 end 25 end 26 27 def show 28 @images = @product.images 29 gon.images = @images.length 30 @sell_user = @product.seller 31 @sell_other_products = Product.where(seller_id: @product.seller_id) 32 @sell_product_brand = @product.brand 33 @sell_product_category = @product.category 34 35 if @product.brand_id.present? && @product.category_id.present? 36 @related_items = Product.where(brand_id: @product.brand_id, category_id: @product.category_id).where.not(id: @product.id) 37 else @product.brand_id.present? || @product.category_id.present? 38 @related_items = Product.where("brand_id = ? or category_id = ?", @product.brand_id, @product.category_id) 39 end 40 end 41 42 def destroy 43 if current_user.id == @product.seller_id 44 if @product.destroy 45 redirect_to root_path 46 else 47 render :show 48 end 49 end 50 end 51 52 def item_show 53 @image = @product.images[0] 54 end 55 56 57 58 def transaction 59 @product = Product.find(params[:format]) 60 end 61 62 private 63 def product_new 64 @product = Product.new 65 end 66 67 68 def completed_transaction 69 ActiveRecord::Base.transaction do 70 71 @product = Product.find(params[:id]) 72 require 'payjp' 73 Payjp.api_key = PAYJP_SECRET_KEY 74 75 Payjp::Charge.create( 76 amount: @product.price, 77 card: params['payjp-token'], 78 currency: 'jpy', 79 ) 80 @product.update!(buyer_id: current_user.id) 81 end 82 end 83 84 85 def product_params 86 params.require(:product).permit( 87 :name, 88 :info, 89 :price, 90 :category_id, 91 :size_id, 92 :status, 93 :delivery_fee_owner, 94 :shipping_method, 95 :delivery_date, 96 :prefecture, 97 images_attributes: [:id,:product_id, image: []], 98 brand_attributes: [:name] 99 ).merge(seller_id: current_user.id,sell_status_id: 1) 100 end 101 102 def product_info 103 @product = Product.find(params[:id]) 104 end 105end

newhtmlhaml

1 .l-contener 2 .signup-panel__inner 3 = form_for(@product, url: sell_path, html: {multiple: true ,method: :post}) do |f| 4 .sell-contents 5 %h2.l-single-head 商品の情報を入力 6 / 画像投稿 ▼ 7 .sell-contents 8 %h3.sell-form-title 9 出品画像 10 %span.form-require.sell 必須 11 %p.sell-contents__comment 最大4枚までアップロードできます 12 .sell-dropbox_container 13 = f.fields_for :images do |i| 14 .sell-dropbox-items 15 %ul.sell-dropbox-preview 16 .sell-dropbox-uploader#droparea 17 .visible-pc#drop 18 ドラッグアンドドロップ 19 %br またはクリックしてファイルをアップロード 20 = i.file_field :image, class: "product_images", id:"btn", multiple: true, name:"images[image][]"

###現状
現状1枚の画像は保存されるのですが、2枚以上選択したときに最新のものに上書きされて保存されてしまいます。
複数の写真を紐づけたいです。

アドバイスお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問、というか確認なのですが、
def create
の@product.saveの時点でimagesのレコードが保存され、画像ファイルもアップされていますか?

accept_nested_attribute_forを使っていれば子レコードの保存は具体的に処理に書かなくてもされるはずです。

viewのfields_forのなかで、
file_fieldのnameがいらない気がします。

もう一度まずは一対多のレコードの保存をしっかりおさらいしてみてはいかがでしょう?

投稿2018/12/31 15:42

motozzi

総合スコア86

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiro610

2019/01/02 13:03

motozziさん アドバイスありがとうございます。 >accept_nested_attribute_forを使っていれば子レコードの保存は具体的に処理に書かなくてもされるはずです。 レコードが1つのみの場合はそのようですが、複数レコードを作成する時にeach文を作成するという記事を見つけ実装した次第でございます。もう少しここらへん勉強してみます! >file_fieldのnameがいらない気がします。 multipleの場合、明示的に[]をつけないとうまくいかないようでしたので、記載いたしました。 こちらの質問に関して、multipleは同時に複数ファイルを選択した場合に、複数投稿が可能という事がわかりました。1つ1つ選択した場合は最新のものに上書きされてしまうみたいです。 そのため上記解決いたしました。 年始にアドバイスいただき誠にありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問