Forum: Ruby on Rails has_one :dependent => true question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Zack C. (Guest)
on 2006-01-05 04:09
(Received via mailing list)
Hello,

I have two classes that are self explanatory and are listed below.

class User < ActiveRecord::Base
  belongs_to :account
end

class Account < ActiveRecord::Base
  has_one :account_owner, { :dependent => true, :class_name => "User",
:conditions => "is_account_owner = 1" }
  has_many :users
end

In the signup controller when an account is created one user is created
as
well that is the account_owner (similar to how Basecamp does it).  My
question is how to ensure that either the account is created and the
user is
created or nothing is saved.

It seems like the only way to do this is to save the Account object then
save the User object.  Is there a best practices way of doing this?

Essentially the sql you want to spit out is:

start transaction;
  insert into accounts (...) values (...);
  insert into users (account_id, ...) values (last_insert_id(), ...);
commit;


Thanks,
Zack
Carlos Y. Okada (Guest)
on 2006-01-05 14:15
(Received via mailing list)
The following works in a has_many relationship. I believe will work for
has_one as well:

Assuming you params[:account] returns a hash that maps to Accounts as
well
to User, in account_controller:

def create
  @account = Account.new(params[:account])
  @account.account_owner.create(params[:account])
  @account.save
...
end

Okada.


2006/1/4, Zack C. <removed_email_address@domain.invalid>:
Jarkko L. (Guest)
on 2006-01-05 18:44
(Received via mailing list)
Hi Zack,

On 5.1.2006, at 4.06, Zack C. wrote:

>   has_one :account_owner, { :dependent => true, :class_name => "User",
>
> It seems like the only way to do this is to save the Account object
> then
> save the User object.  Is there a best practices way of doing this?

Transaction, baby:

User.transaction do
	# the code that creates both user and account here (Okada already
touched this)
end

//jarkko
Zack C. (Guest)
on 2006-01-05 20:57
(Received via mailing list)
For anyone having a similar problem hopefully this will help.

BTW... Thanks to Carlos and Jarkko for your suggestions.

There is the test snippet of code that did the trick:

@account = Account.new :account_name => "Dev account"
@account.build_account_owner :username => "test_user", :password =>
"password", :name => "Test User", :email_address => 
"removed_email_address@domain.invalid",
:is_account_owner => 1
if @account.valid? && @account.account_owner.valid?
  @account.save
end

This does result in the desired transaction

BEGIN
  INSERT INTO accounts ...
  INSERT INTO users ...
COMMIT

The valid? check must be done because ActiveRecord will happily save the
account but not the user if there are validation problems on the user
object.

Hope this helps.

Zack
This topic is locked and can not be replied to.