Rails Bug? create_association delete existing record if duplicate exist

I am so frustrating by Rails!

I have two very simple models:

    User     has_one :profile, :dependent => :destroy

    Profile     belongs_to :user, :conditions => { :registered => true }     validates :user_id, :uniqueness => { :on => :create, :message => "can only have one profile!" }

I am trying to create Profile table without the default 'id' primary key. I want to use user_id to find profile instead (not necessary to be the primary key, I can use Profile.find_by_user_id.). But there are issues with or without the default 'id' PK.

Issue #1: (profile with default "id" PK) If a user has a profile already, and I run build_profile from the user again, it will report a validation error and DELETE my exist profile record (What the hell?):

    ruby-1.9.2-p290 :037 > User.find(15).create_profile!     User Load (1.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 15 LIMIT 1     (0.1ms) SAVEPOINT active_record_1     (0.3ms) SELECT 1 FROM `profiles` WHERE `profiles`.`user_id` = BINARY 15 LIMIT 1     (0.2ms) ROLLBACK TO SAVEPOINT active_record_1     Profile Load (0.3ms) SELECT `profiles`.* FROM `profiles` WHERE `profiles`.`user_id` = 15 LIMIT 1     (0.1ms) SAVEPOINT active_record_1     SQL (0.2ms) DELETE FROM `profiles` WHERE `profiles`.`id` = 5     (0.1ms) RELEASE SAVEPOINT active_record_1     ActiveRecord::RecordInvalid: Validation failed: User can only have one profile!

Issue #2: (Profile with ":id => false" set in migration) With or without a exist profile, every time create_profile is called, it try to delete something with the non-exist 'id' field, which in turn cause a error:

    ruby-1.9.2-p290 :035 > User.find(15).create_profile!     User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 15 LIMIT 1     (0.1ms) SAVEPOINT active_record_1     SQL (0.2ms) INSERT INTO `profiles` (`created_at`, `updated_at`, `user_id`) VALUES ('2011-11-03 03:49:35', '2011-11-03 03:49:35', 15)     (0.1ms) RELEASE SAVEPOINT active_record_1     Profile Load (0.3ms) SELECT `profiles`.* FROM `profiles` WHERE `profiles`.`user_id` = 15 LIMIT 1     (0.1ms) SAVEPOINT active_record_1     SQL (0.5ms) DELETE FROM `profiles` WHERE `profiles`.`` = NULL     (0.1ms) ROLLBACK TO SAVEPOINT active_record_1     ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'profiles.' in 'where clause': DELETE FROM `profiles` WHERE `profiles`.`` = NULL

I am so confused with this call, what does it trying to delete?

    SQL (0.5ms) DELETE FROM `profiles` WHERE `profiles`.`` = NULL

Don't bother. Even if you don't want to use the id just allow rails to include it. Life will be much simpler if you go along with the rails conventions.

Colin

Don't bother. Even if you don't want to use the id just allow rails to include it. Life will be much simpler if you go along with the rails conventions.

Colin

Thanks for your advice, Colin. I think you are right.

Any idea why 'create_association' initiate a SQL DELETE on duplicated exist record, when I have the uniqueness validation on?

I don't know as I have not done similar things. Could it be to do with the dependent destroy, thinking it has to delete the old one when you create the new one? As I said that is only an idea though. It might be worth removing the destroy to see what the effect is.

Colin