LoginSignup
3
6

More than 5 years have passed since last update.

fields_forにハマった

Posted at

日記に画像を登録するのに、diaryモデルとimageモデルを使用して実装。

画像の登録はcarrierwaveを使いました。

別モデルのデータを表示するにはアソシエーションとfields_forでのフォーム生成が必要。

アソシエーション

diary:image = 1:多 の関係性なので

diary.rb
has_many :images, dependent: :destroy
#オプション(dependent: :destroy)で日記が消えたらそれに関連する画像も消える設定にした。
image.rb
belongs_to :diary

リファレンスキー追加

ターミナル
rails g migration add_references_to_images diary:references
create_images.rb
class CreateImages < ActiveRecord::Migration[5.2]
  def change
    create_table :images do |t|
      t.string :name
      t.references :diary, foreign_key: true #追記

      t.timestamps
    end
  end
end
add_references_to_images.rb
class AddReferencesToImages < ActiveRecord::Migration[5.2]
  def change
    add_reference :images, :diary, foreign_key: true
  end
end

これでimagesテーブルにdiary_idが入る。

gemインストール

Gemfile
gem 'carrierwave'
ターミナル
bundle install

uploader追加

ターミナル
rails g uploader image
image.rb
mount_uploader :name, ImageUploader
#nameカラムに画像のデータが入ります。

入力フォーム作成

_form.html.erb(diary)

<%= form_for(@diary) do |form| %>
  <% if @diary.errors.any? %>
    <div id="error_explanation">
      <%= pluralize(angel.errors.count, "error") %> prohibited this diary from being saved:

  <div class="field">
    <%= form.label :date %>
    <%= form.date_field :date, value: Time.now.strftime("%Y-%m-%d") %>
  </div>

   <div class="field">
    <%= form.label :content %>
    <%= form.text_area :content %>
  </div>

#異なるモデル(imageモデル)をいじるときはform.fields_forを使う
  <%= form.fields_for :images do |image| %> 
    <div class="field">
      <%= image.label :image %> #表示名
      <%= image.file_field :name %> #ファイル選択ボックスを生成し、データの送り場所を指定
      <%= image.hidden_field :id %>
    </div>
  <% end %>


  <div class="actions">
    <%= form.submit %>
  </div>

<% end %>

<%= link_to 'Back', diaries_path %>

accepts_nested_attributes_for

diaries_controller.rb
class DiariesController < ApplicationController
    def new
      @diary = current_user.diaries.new
      @diary.images.build
    end

    def create
      @diary = current_user.diaries.build(diary_params)
      if @diary.save
        redirect_to @diary, notice: 'diary was successfully created.'
      else
        render :new
      end
    end

  private

    def diary_params
      params.require(:diary).permit(:date ,:gift ,:content ,:user_id ,:angel_id,
        images_attributes: [:id, :name, :_destroy])#編集や削除の際にid,;_destroyが必要らしい
    end
end
diary.rb
accepts_nested_attributes_for :images

モデルでaccepts_nested_attributes_forを指定することでコントローラのstrongparameter内でimages_attributeを使ってカラムを指定することができる

画像の表示

show.html.erb
<%= image_tag @diary.images.first.name.to_s %>
3
6
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
6