# \[Rails 2.3\] Adding a "phase" to the ActiveRecord Lifecycle

**URL:** <https://www.ruby-forum.com/t/rails-2-3-adding-a-phase-to-the-activerecord-lifecycle/186895>\
**Category:** Rails\
**Created:** [April 13, 2010, 10:42pm UTC](https://www.ruby-forum.com/t/rails-2-3-adding-a-phase-to-the-activerecord-lifecycle/186895 "2010-04-13T22:42:21Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Phoenix\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5e9695/32.png) [@Phoenix\_R](https://www.ruby-forum.com/u/Phoenix_R)\
**Post date:** [April 13, 2010, 10:42pm UTC](https://www.ruby-forum.com/t/rails-2-3-adding-a-phase-to-the-activerecord-lifecycle/186895/1 "2010-04-13T22:42:21Z")

</div>

I’ve run into a situation where it seems to me that if I could  
“extend” the typical AR lifecycle to add another “phase” or step to  
it, it would simplify things. My problem is that I just don’t know  
how to do that, and I haven’t been able to find documentation anywhere  
on it!

I’m working on an e-commerce application that’s somewhat complex. Due  
to constraints of the organization, I can’t have accounts or  
authentication. My theoretical approach is to store an “order ID” in  
a user’s session, and of course all selects/updates etc. will be only  
for that ID from their session, thus keeping the current status of the  
order in the database at all times. If it were something simple I’d  
just store an array of object IDs in the user’s session, but there are  
several different kinds of products/services to buy, each with vastly  
different models and various requirements (“if you have this you must  
have that but MUST NOT have this”, etc.).

The AR lifecycle question comes into play because I’d like to add some  
form of validation on the Order model, but ONLY before and after the  
user’s card is charged.

So here’s a simple example -

Order \< ActiveRecord::Base  
belongs\_to :object  
has\_many :item\_joins  
has\_many :items, :through =\> :item\_joins  
has\_many :other\_item\_joins  
has\_many :other\_items, :through =\> :other\_item\_joins

# … and so on …

end

Because the user can add multiple items and other items to their  
order, as well as set the “object” on their order at any point in the  
ordering process, I can’t call the validations I want after save. I’d  
much rather have a before/after “card\_charged” step in the lifecycle,  
and run a validation before the card is charged, then one after it’s  
charged.

So, for example, I’d like to be able to do something like:

Order \< ActiveRecord::Base

# …associations as above…

before\_charged :ensure\_not\_empty

private  
def ensure\_not\_empty  
if self.items.count \< 1 and self.other\_items.count \< 1  
errors.add\_to\_base(“Your order is empty!”)  
return false  
end  
end

And this would need to fire when Order#charge\_card (or similarly named  
method) is called, canceling the call to Order#charge\_card if false is  
returned.

I took a quick look at state machines (aasm), and I have to confess  
that I don’t know much about a state machine or how one works other  
than very basic theory. It seems like it might be overkill to me,  
when all I want to do is add two methods to the lifecycle as above.  
However, I’m fully willing to consider the possibility that what I’m  
suggesting here is outside the realm of best practices.

Any ideas as to how I could add these steps to the lifecycle of just  
this object?

---

<div class="post-metadata">

**Author:** ![Phoenix\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5e9695/32.png) [@Phoenix\_R](https://www.ruby-forum.com/u/Phoenix_R)\
**Post date:** [April 14, 2010, 2:16pm UTC](https://www.ruby-forum.com/t/rails-2-3-adding-a-phase-to-the-activerecord-lifecycle/186895/2 "2010-04-14T14:16:36Z")

</div>

On Tuesday 13 April 2010, Phoenix R. wrote:

> Because the user can add multiple items and other items to their  
> order, as well as set the “object” on their order at any point in the  
> ordering process, I can’t call the validations I want after  
> save. I’d much rather have a before/after “card\_charged” step in  
> the lifecycle, and run a validation before the card is charged, then  
> one after it’s charged.

I think the best way would be to use a state machine, as you indicated  
yourself in a paragraph I snipped. Second best would be to use  
conditional validations, see the :if and :unless options on all the  
validates\_something methods.

Michael

–  
Michael S.  
[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[http://www.schuerig.de/michael/](http://www.schuerig.de/michael/)
