# Boolean database + Site Design/Architecture Question

**URL:** <https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467>\
**Category:** Rails\
**Created:** [October 21, 2008, 9:58pm UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467 "2008-10-21T21:58:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 21, 2008, 9:58pm UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/1 "2008-10-21T21:58:40Z")

</div>

Hi all,

As usual, you’ve all been very helpful in the past and I thank you for  
continuing to help myself and others.

Today I have the following code/database architecture question which I  
would like you guys to help me out with.

## Children Table (user has\_many children)

…  
is\_lost boolean, default =\> false  
is\_found boolean, default =\> false  
…

Basically, a child is “safe” if he is not flagged as lost or found (so a  
child has 3 possible states: safe, lost, found).

I created a custom validation to avoid a child from being both lost AND  
found with this:

```auto
def validate
if is_lost? and is_found?
      errors.add_to_base("A child can't be lost <i>AND</i> found at the
same time!")
    end
end
```

This all works great and validates correctly. HOWEVER, the only way I’ve  
been able to select if a child is lost or found is through check boxes  
(not the best way to do this). I think a drop down box would be the  
better solution to select if a child is either lost or found (or safe)

My question is this:

Is this the best way to achieve what I am trying to do? Is it better to  
just have a column in my table named “status” where the values would be  
either Safe, Lost, Found and remove the is\_lost and is\_found boolean  
columns instead?

If the current way I designed it is good, how can I create a drop down  
box that could handle both the is\_lost and is\_found data?

I know this is a disaster (in my eyes) but I would like the opinions and  
suggestions of you experienced folks.

Thank you!!!  
-Tony

P.S. Let me know if you need more info or code to help you understand  
this.

---

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 21, 2008, 10:05pm UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/2 "2008-10-21T22:05:16Z")

</div>

I would go with a single ‘status’ field.

---

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 21, 2008, 10:12pm UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/3 "2008-10-21T22:12:50Z")

</div>

Roy P. wrote:

> I would go with a single ‘status’ field.

Thanks Roy, I appreciate the reply. I guess I could just do a…

```auto
if @child.status == 'lost'
  ...
```

I did like the elegance of boolean for things like:

```auto
if @child.is_lost?
  ...
```

Any other suggestions or opinions?

---

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 21, 2008, 10:21pm UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/4 "2008-10-21T22:21:40Z")

</div>

Well, you can still have those is\_whatever? methods–just write them on  
the model your own self:

class Child  
def is\_lost?  
self.status == ‘lost’  
end  
def is\_found?  
self.status == ‘found’  
end  
def is\_safe?  
self.status = ‘safe’  
end  
end

You could even write your own setters (def is\_safe=(new\_val)), tho that  
may be taking it too far…

---

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 21, 2008, 10:36pm UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/5 "2008-10-21T22:36:20Z")

</div>

Roy P. wrote:

> Well, you can still have those is\_whatever? methods–just write them on  
> the model your own self:

TouchÃ©. Can’t believe I didn’t think about that! Thank you!!

---

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 22, 2008, 12:05am UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/6 "2008-10-22T00:05:11Z")

</div>

First and foremost, shouldn’t your model be called Child? A single child  
shouldn’t be called “a children”, but that’s how you have it set up.  
Having  
it as is won’t destroy the universe, but it will end up getting really  
confusing sooner or later. Rails knows that “children” is the plural  
form  
of “child”. Open the rails console and type “child”.pluralize to see for  
yourself.

That aside, since Children is a stateful object, you should consider the  
Acts  
As State Machine plugin. All you need is the plugin and a “state”  
(varchar)  
column in the model’s database table. This gives you all kinds of neat  
functionality.

In your rails app root, do this little number:  
script/plugin install  
[http://elitists.textdriven.com/svn/plugins/acts\_as\_state\_machine/trunk/](http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/)

We will configure your model to have three states: “safe”, “lost”,  
and “found”. In your Children model, add the following:

#set the default state  
acts\_as\_state\_machine, :initial =\> :safe

# declare three states: “safe”, “lost”, and “found”

state :safe  
state :lost  
state :found

# configure state methods

event :lost do  
transitions :from =\> :safe, :to =\> :lost  
transitions :from =\> :found, :to =\> :lost  
end  
event :found do  
transitions :from =\> :safe, :to =\> :found  
transitions :from =\> :lost, :to =\> :found  
end  
event :safe do  
transitions :from =\> :lost, :to =\> :safe  
transitions :from =\> :found, :to =\> :safe  
end

That’s it. Now the following methods will work to check the state:  
@child.safe? # true/false  
@child.lost? # true/false  
@child.found? # true/false

The “events” that you declared are used to change the object’s state,  
using  
event!. For example, to change a safe child to lost, you would call:  
@child.lost!  
Normally, you would want to name your “events” some kind of verb. This  
makes  
the method easier to read and understand, but your situation is  
peculiar. I  
guess you should leave them as is to avoid any further confusion.

You can tell AASM to call additional methods when transitioning between  
states, if you wish. You can also block transitions unless certain  
conditions  
are met. Read up on the callbacks and guard functions here:  
[http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts\_as\_state\_machine/](http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts_as_state_machine/)  
(site is currently showing a blank page, but it’s there, I swear!)

---

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 23, 2008, 4:05pm UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/7 "2008-10-23T16:05:11Z")

</div>

I hate to bump and annoy, but can anyone offer a suggestion on my last  
reply?

Thanks!

-Tony

---

<div class="post-metadata">

**Author:** ![bagadoughnuts](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bagadoughnuts](https://www.ruby-forum.com/u/bagadoughnuts)\
**Post date:** [October 22, 2008, 6:19am UTC](https://www.ruby-forum.com/t/boolean-database-site-design-architecture-question/151467/8 "2008-10-22T06:19:20Z")

</div>

Patrick Sullivan wrote:

> As State Machine plugin. All you need is the plugin and a “state”  
> (varchar)  
> column in the model’s database table. This gives you all kinds of neat  
> functionality.

Thank you immensely for bring that plugin to my attention. As for the  
child naming, I’m using pseudo code for the most part. Sorry about that.

I just have a (silly) question about the event! calls… where do I put  
them? 🙂 I tried searching for it but didn’t find an exact answer.

I was able to make the state column into a drop box with the three  
states like so (in a hurry):

```auto
<%= select :child, :state, { "Safe" => "safe", "Lost" => "lost", "Found" 
=> "found"} %>
```

So it updates and displays the state just fine (@child.state). HOWEVER,  
I’m sure the use of @child.lost!, @child.found!, and @child.safe! is  
there for a reason. What is the best way to go about implementing this?

From just some quick brainstorming I’m thinking the below if block in  
the update (and create) method would work, but perhaps there is a better  
way?

```auto
def update
    @child = Children.find(params[:id])

    if params[:state]=='lost'
      @child.lost!
    elsif params[:state]=='found'
      @child.found!
    else
      @child.safe!
    end

...
end
```

Also, is it possible to use more than one act\_as\_state\_machine per  
model? I’m assuming you can by assigning a :column =\> ‘column\_name’. But  
confirmation would be nice.

Thank you so much again!!!  
-Tony
