PDA

View Full Version : transactions (commit and rollbacks)


eiji
March 12th, 2006, 06:44 AM
hi there. 2 days experience in ruby on rails and im loving it already. though i have a lot of questions, i mean a lot. as others i dont really seem to get. and my head is aching as they want me to create apps very fast, and i havent read much..

one question is the transactions.. could someone help me here?

i must make a transaction here that when one saving into database fails, it would rollback all the transactions made on that block of transaction.

my codes look like this :

/controller/signup
class SignupController < ApplicationController
def save
@user = User.new()
@user.usertype_id = 1
if @user.save
@memberaccount = Memberaccount.new(params[:memberaccount])
@memberaccount.user_id = @user.id
@memberaccount.sysdate = Date.today
if @memberaccount.save
redirect_to :action => 'thankyou'
else
# flash[:notice] = 'an error has occured when signing up. please retry1'
render :action => 'index'
end
else
flash[:notice] = 'an error has occured when signing up. please retry2'
render :action => 'index'
end
end
end


now here is a two part transaction that first saves into the users database and when it succeeds and then again enters more in the memberaccount database. now my question is when the "@memberaccount.save" had an error.. how do i rollback the save that occured on the users?

i have seen some transactions stuff but how do i squeeze this in my codes??

e.g.
Account.transaction(account1, account2) do
account1.withdraw(100)
account2.deposit(100)
end


e.g.2
Account.transaction do
User.transaction do
yada_yada
end
end

thanks for the help :D

motobass
March 16th, 2006, 10:41 PM
Hi eiji. Reading over the docs on http://api.rubyonrails.com - in particular the pages on ActiveRecord::Transactions::ClassMethods and ActiveRecord::Base, leads me to believe that if you have certain criteria met, you do not need to explicitly declare transactions - you get them for free, if...

1) your database supports it (postgreSQL, or MySQL with InnoDB tables, for example)
2) your model declares the memberaccount as a "child" of user. User has a MemberAccount, MemberAccount belongs to User.

If so, you can code like so and it should take care of itself. Watch your development.log for the SQL that is actually run.

... (the following has not been tested!)

@user = User.new()
@user.usertype_id = 1
@user.memberaccount = Memberaccount.new(params[:memberaccount])

if @user.save
redirect_to :action => 'thankyou'
else
...
end

rob
March 16th, 2006, 10:49 PM
That's one of the reasons I haven't had to deal with transactions, they're woven into ActiveRecord in a very helpful way :)

eiji
March 20th, 2006, 10:39 AM
wow! is that how it works? ill try that out! :D

wait fo my feed back please.. thanks so much so much:D

eiji
March 21st, 2006, 10:19 AM
help.. i had a problem..

here is my controller now..

class SignupController < ApplicationController
def index
@member_account = MemberAccount.new
@user_types = UserType.find_all
@persona_types = PersonaType.find_all
end

def save
@user = User.new()
@user.user_type_id = 1
@user.member_accounts = MemberAccount.new(params[:member_account])

if @user.save
redirect_to :action => 'thankyou'
else
flash[:notice] = 'an error has occured when signing up. please retry1'
render :action => 'index'
end
end

def thankyou
end
end


in case needed here are my models

class MemberAccount < ActiveRecord::Base
#database relationship
belongs_to:user
has_many:access_points
belongs_to:avatar
has_many:personas
has_many:contacts

#validation
validates_uniqueness_of :username, :message => "already exists"
validates_format_of :username,
:with => /^\w+$/,
:message => "cannot contain whitespace"
validates_presence_of :username, :password, :first_name, :last_name, :email
validates_format_of :email,
:with => /^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/,
:message => "incorrect format"

end


class User < ActiveRecord::Base
belongs_to:user_type
has_many:member_accounts
end


the error is now :
undefined method `MemberAccount=' for #<User:0x3892588>

i have tried to change @user.member_account in differnet formats, like MemberAccount, memberaccount, etc. once i tried member_accounts it had an error like this :
undefined method `each' for #<MemberAccount:0x3800c08>

also, how would the @user.id there be put to MemberAccounts?? is that automatic?? if so, cool! :D

and umn.. if im not abusing my questioning.. umn..
i am also going to add another table there.. called Personas which is going to saved after saving the memberaccounts.. the ID generated by the memberaccount would then be entered there.. how am i going to do that too?

thanks so much! :D
hope i am not much of a burden