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

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

ただいまの
回答率

89.63%

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 679

hiro610

score 6

前提

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

  has_many :images, dependent: :destroy
  accepts_nested_attributes_for :images, limit: 4
  accepts_nested_attributes_for :brand
  belongs_to :product, optional: true
  mount_uploader :image, ImageUploader

実現したい事

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

コード

class ProductsController < ApplicationController
  before_action :product_new, only:[:new]
  before_action :product_info, only: [:show, :item_show, :destroy]

  def new
    @images = @product.images.build
  end

  def create
    @product = Product.new(product_params)
    @product.brand = Brand.find_or_create_by(name: @product.brand.name) if @product.brand.name

    respond_to do |format|
      if @product.save
        params[:images][:image].each do |i|
          binding.pry
          @product.images.create(product_id: @product.id, image: i)
        end
        format.html { redirect_to root_path}
        # redirect_to root_path
      else
        render action: :new
      end
    end
  end

  def show
    @images = @product.images
    gon.images = @images.length
    @sell_user = @product.seller
    @sell_other_products = Product.where(seller_id: @product.seller_id)
    @sell_product_brand = @product.brand
    @sell_product_category = @product.category

    if @product.brand_id.present? && @product.category_id.present?
      @related_items = Product.where(brand_id: @product.brand_id, category_id: @product.category_id).where.not(id: @product.id)
    else @product.brand_id.present? || @product.category_id.present?
      @related_items = Product.where("brand_id = ? or category_id = ?", @product.brand_id, @product.category_id)
    end
  end

  def destroy
    if current_user.id == @product.seller_id
      if @product.destroy
        redirect_to root_path
      else
        render :show
      end
    end
  end

  def item_show
    @image = @product.images[0]
  end



  def transaction
    @product = Product.find(params[:format])
  end

  private
  def product_new
    @product = Product.new
  end


  def completed_transaction
    ActiveRecord::Base.transaction do

      @product = Product.find(params[:id])
      require 'payjp'
      Payjp.api_key = PAYJP_SECRET_KEY

      Payjp::Charge.create(
        amount:  @product.price,
        card:    params['payjp-token'],
        currency: 'jpy',
      )
      @product.update!(buyer_id: current_user.id)
    end
  end


  def product_params
    params.require(:product).permit(
      :name,
      :info,
      :price,
      :category_id,
      :size_id,
      :status,
      :delivery_fee_owner,
      :shipping_method,
      :delivery_date,
      :prefecture,
      images_attributes: [:id,:product_id, image: []],
      brand_attributes: [:name]
    ).merge(seller_id: current_user.id,sell_status_id: 1)
  end

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

現状

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/02 22:03

    motozziさん
    アドバイスありがとうございます。
    >accept_nested_attribute_forを使っていれば子レコードの保存は具体的に処理に書かなくてもされるはずです。
    レコードが1つのみの場合はそのようですが、複数レコードを作成する時にeach文を作成するという記事を見つけ実装した次第でございます。もう少しここらへん勉強してみます!

    >file_fieldのnameがいらない気がします。
    multipleの場合、明示的に[]をつけないとうまくいかないようでしたので、記載いたしました。

    こちらの質問に関して、multipleは同時に複数ファイルを選択した場合に、複数投稿が可能という事がわかりました。1つ1つ選択した場合は最新のものに上書きされてしまうみたいです。
    そのため上記解決いたしました。

    年始にアドバイスいただき誠にありがとうございます!!

    キャンセル

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

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる