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

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

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

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Ruby on Rails

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

Q&A

1回答

1573閲覧

Rails5でUPDATE処理時に関連のデータが削除される挙動について

tatsuhit0

総合スコア1

Ruby on Rails 5

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Ruby on Rails

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

0グッド

0クリップ

投稿2021/08/01 07:29

質問をご覧いただきましてありがとうございます。
Railsでの開発でDBにPostgresを利用しています。

RailsはAPIモードで使用しています。

以下の環境でUserとProfileを同時にUpdateを実行すると関連モデルが一旦削除されてから新たにInsertされていることに気づきました。

モデルは下記の通りです

User(has_one=>Profile)

ruby

1class User < ActiveRecord::Base 2 3 devise :database_authenticatable, 4 :registerable, 5 :recoverable, 6 :rememberable, 7 :validatable, 8 authentication_keys: [:login_id] 9 10 11 12 include DeviseTokenAuth::Concerns::User 13 14 15 has_one :profile, dependent: :destroy 16 accepts_nested_attributes_for :profile 17end

Profile(belongs_to=>User)

class Profile < ApplicationRecord belongs_to :user accepts_nested_attributes_for :user end

UserController

Ruby

1class Admin::UsersController < ApplicationController 2 before_action :set_user, only: %i[show update destroy] 3 4 # PATCH/PUT /admin/users/1 5 def update 6 test_params = { profile_attributes: { first_name: 'AAA' } } 7 8 if @user.update(test_params) 9 render json: @user 10 else 11 render json: @user.errors, status: :unprocessable_entity 12 end 13 end 14 15 private 16 17 # Use callbacks to share common setup or constraints between actions. 18 def set_user 19 @user = User.find(params[:id]) 20 end 21 22 23end 24

上記のコードでUserControllerのupdateを実行すると、Profileのfirst_nameが更新されるのですが、実際のログを見ると更新されているのではなく、一旦既存のProfileレコードを削除してあらたにレコードをInsertしている挙動でした。

この動作について、少し気持ち悪い感じがするのですが通常の挙動なのでしょうか?

その際の、ログも下記に記載いたします。

log

1(0.4ms) BEGIN 2 ↳ app/controllers/admin/users_controller.rb:38 3 Profile Load (0.7ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 LIMIT $2 [["user_id", 114], ["LIMIT", 1]] 4 ↳ app/controllers/admin/users_controller.rb:38 5 Profile Destroy (0.6ms) DELETE FROM "profiles" WHERE "profiles"."id" = $1 [["id", 145]] 6 ↳ app/controllers/admin/users_controller.rb:38 7 Location Load (0.9ms) SELECT "locations".* FROM "locations" WHERE "locations"."id" = $1 LIMIT $2 [["id", 3], ["LIMIT", 1]] 8 ↳ app/controllers/admin/users_controller.rb:38 9 Profile Create (0.7ms) INSERT INTO "profiles" ("user_id", "name", "created_at", "updated_at", "first_name") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["user_id", 114], ["name", "AAA "], ["created_at", "2021-08-01 16:05:37.273040"], ["updated_at", "2021-08-01 16:05:37.273040"], ["first_name", "AAA"]] 10 ↳ app/controllers/admin/users_controller.rb:38 11 (1.5ms) COMMIT

皆様の知識を共有していただければ非常に助かります。
どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

既存のprofileを更新させたい場合、そのidprofile_attributesの中に入れて渡す必要があります。

idがない場合、「関連したprofile新規作成する」ものと解釈されます(has_oneなので、前あった方は削除されます)。

投稿2021/08/01 09:58

maisumakun

総合スコア145208

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問