LoginSignup
5
3

More than 3 years have passed since last update.

【Rails】フォーム内で、異なるモデルのデータを送信したい

Posted at

1:1の関係のモデル同士を関連づけ、フォームにそれぞれのモデルデータを同時に送信できるようにしたい。
つまり、formメソッド内で、2つのデータモデルを扱えるようにするのが今回の目的になります。

今回は、UserモデルとUser_profileモデルを1:1の関係性にして、formメソッド内でどちらのユーザー情報も同時に編集できるようにします。

M

マイグレーションファイル
class CreateUserProfiles < ActiveRecord::Migration[6.0]
  def change
    create_table :user_profile do |t|
      t.string :twitter_url
      t.string :program_lang
      t.string :image
      t.references :user, foreign_key: true
      t.timestamps
    end
  end
end

t.references :user, foreign_key: true
外部キーを設定することで、UserモデルとUser_profileモデルを紐付けます。


$ rails db:migrate
models/user_profile.rb
class Prof < ApplicationRecord
  belongs_to :user
end
models/user.rb
class User < ApplicationRecord
  has_one :user_profile
  accepts_nested_attributes_for :user_profile
end

accepts_nested_attributes_for :user_profileは、ネストされるフォームデータに備えてのものになります。
具体的には、ストロングパラメータ時に{ user: { user_profile_attributes: { program_lang: 〇〇, twitter_url: 〇〇, image: 〇〇 } } }という形でまとめることができます。

C

users_controller.rb
def create
  @user = User.new(user_params)
  @user.build_user_profile
  if @user.save
  ・・・
  end
end

private

def user_params
  params.require(:user).permit(:name, :email, :password, user_profile_attributes: [:id, :program_lang, :twitter_url, :image])
end

ここで、注目すべきなのが@user.build_user_profile
あらかじめuser_profileモデルのインスタンスの作成をしていないと、View側のフォームが表示されません。

V

edit.html.erb
.container
  = form_with model: @user, local: true do |form|
    = form.fields_for :user_profile do |prof|
      .form-image
        = prof.file_field :image

    .form-group
      = form.text_field :name
      = form.text_field :email

    = form.fields_for :user_profile do |prof|
      .form-group
        = prof.text_field :program_lang
        = prof.text_field :twitter_url

    .row
      = form.submit "編集"

フォームの中にさらに別のモデルデータを認識してくれるのが、fields_for
フォームの中にフォームを作ることで、編集ボタンを押すだけでまとめてサーバー側にデータを送信してくれます。

5
3
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
5
3