LoginSignup
1
1

More than 3 years have passed since last update.

1つのformで複数のmodelにデータを登録する carrier waveを使って

Last updated at Posted at 2019-07-18

1つのformで親と子の関係にあるmodelにそれぞれのdataを振り分け保存する方法。
別のmodelやdbにデータを同時保存する方法。

itemが親、imageが子の関係(1:多)

item.rb
class Item < ApplicationRecord
    has_many :images
    accepts_nested_attributes_for :images
    #親の方にaccepts_nested_attributesの記述を追記
end
image.rb
class Image < ApplicationRecord
    belongs_to :item
    mount_uploader :image, ImageUploader
end

form.haml
 = form_for @item, url: items_path, mehod: :post do |f|
         ## @itemは:itemの形だとうまく行きません。@itemの形で渡してあげてね。
          .formSection
            = f.hidden_field :user_id, value: current_user.id
            .productForm__field.productForm__field--top
              = f.label :画像
              %span.formRequired 必ず入れてね
              %br/
              %p アップロードできます
              %ul.formUploader
                = f.fields_for :images do |i|
               ## formをformでネストさせる方法でimageをcontrollerに渡してあげる。
                  = i.label :image,"クリックしてアップロード"
                  = i.file_field :image

##この時のformのhtmlのinput nameはこんな形になってます。
<input type="file" name="item[images_attributes][0][image]" id="item_images_attributes_0_image">
item_controller.rb
def new
    @item = Item.new
    @item.images.build
        ##ここでbuildすることにより、親と子が結びついて同時にレコードが作成される。
end

def create
     item = Item.new(item_params)
     item.save
end

private

def item_params
     params.require(:item).permit(:text,images_attributes: [:id,:image])
end

ここでのparamsはこのようになっています。

params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"hogehoge=", "item"=>{"user_id"=>"2", "images_attributes"=>{"0"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00007fdd59c18d40 @tempfile=#<Tempfile:/var/folders/fl/g00000000/T/RackMultipart20190718-40737-1kgrqpj.jpg>, @original_filename="hoge.jpg", 
@content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"item[images_attributes][0][image]\"; filename=\"hoge.jpg\"\r\nContent-Type: image/jpeg\r\n">}}, "price"=>"10000"}, "commit"=>"作成する", "controller"=>"items", "action"=>"create"} permitted: false>

以下は1:1の関係時の書き方。
itemとimageの関係(1:1)

item.rb
class Item < ApplicationRecord
    has_one :image
    accepts_nested_attributes_for :image
end
image.rb
class Image < ApplicationRecord
    belongs_to :item
    mount_uploader :image, ImageUploader
end

item_controller.rb
def new
    @item = Item.new
    @item.build_image
        ##ここでbuildの記法を変えるだけ。
end

そんなに変えるところはないですね。


どうもうまく行かない時
まずは、carrier_wave単体で機能するのかどうかを確認してみてもいいかもしれませんね。

undefined method `resize_to_fit' for #<ImageUploader:0x00007fdd57509fb0>

carrier waveの設定が間違っている可能性があります。
Image.uploaderにinclude CarrierWave::MiniMagickの記述はありますか??

htmlのnameのところが
name="item[images_attributes][0][image]"の形になってますか?

@itemになってますか?:itemの形になってないですか??

ActiveRecord::AssociationTypeMismatch
これは忘れましたが、dbのカラムにitem_idのような外部キーは存在してますか?
nameの記述が(いわゆるformの送り方が)違ってないですか?
assosiationやimage_uploaderのmodelの記述は間違ってないですか?(sつけ忘れとか)

1
1
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
1
1