Strange behaviour with the "create_xxx" on has_one association

I have models like this:

class User < ActiveRecord::Base
has_one :user_preference, dependent: :destroy
end

class UserPreference < ActiveRecord::Base
belongs_to :user
end

It works fine when I call this:

$ user.create_user_preference

(0.3ms) BEGIN
User Load (0.9ms) SELECT “users”.* FROM “users” WHERE
“users”.“deleted_at” IS NULL AND “users”.“id” = $1 LIMIT 1 [[“id”,
“055df158-4b3f-43f0-b73a-0c14e0ba7723”]]
UserPreference Exists (0.7ms) SELECT 1 AS one FROM
“user_preferences”
WHERE “user_preferences”.“user_id” =
‘055df158-4b3f-43f0-b73a-0c14e0ba7723’ LIMIT 1
SQL (0.5ms) INSERT INTO “user_preferences” (“created_at”,
“updated_at”,
“user_id”) VALUES ($1, $2, $3) RETURNING “id” [[“created_at”,
“2014-12-08
08:45:57.630670”], [“updated_at”, “2014-12-08 08:45:57.630670”],
[“user_id”, “055df158-4b3f-43f0-b73a-0c14e0ba7723”]]
(1.5ms) COMMIT
(0.2ms) BEGIN
(0.2ms) COMMIT

But, if I call that method again, it will delete the profile record.

$ user.create_user_preference

(0.3ms) BEGIN
User Load (0.8ms) SELECT “users”.* FROM “users” WHERE “users”.
“deleted_at” IS NULL AND “users”.“id” = $1 LIMIT 1 [[“id”,
“055df158-4b3f-43f0-b73a-0c14e0ba7723”]]
UserPreference Exists (0.7ms) SELECT 1 AS one FROM
“user_preferences”
WHERE “user_preferences”.“user_id” =
‘055df158-4b3f-43f0-b73a-0c14e0ba7723’
LIMIT 1
(0.3ms) ROLLBACK
(0.2ms) BEGIN
SQL (0.4ms) DELETE FROM “user_preferences” WHERE
“user_preferences”.“id”
= $1 [[“id”, “9eb6cabd-7c50-4f2b-8562-1159e1c2f4b4”]]
(37.0ms) COMMIT

It looks weird for me. Is it a normal behaviour, or am I doing something
wrong??

This behavior is normal. When a record already exists for has_one, it
deletes the previously existing record for database consistency (
has_many
) . It is a bit similar to has_and_belongs_to_many

when you have User has_and_belongs_to_many categories.

user.categories_ids = [4,5,6] #some array of category ids

its deletes all the existing records and replace it with the new ones.

Cheers

On Mon, Dec 8, 2014 at 2:18 PM, Man Vuong Ha Thanh
[email protected]

On Monday, December 8, 2014 8:48:37 AM UTC, Man Vuong Ha Thanh wrote:

UserPreference Exists (0.7ms) SELECT 1 AS one FROM “user_preferences”

Well the delete makes sense to me - you’re creating a new user
preference,
so the old one should be destroyed since this is a has_one and you’ve
configured the relationship as dependent: :destroy. Not sure why it
doesn’t
create a new one though

Fred

The new one is obviously failing a validation on the user or
user_preference . Check the object for any validation errors.

On Mon, Dec 8, 2014 at 3:31 PM, Frederick C.
<[email protected]