# Active record question

**URL:** <https://www.ruby-forum.com/t/active-record-question/71299>\
**Category:** Ruby\
**Created:** [October 6, 2006, 7:16pm UTC](https://www.ruby-forum.com/t/active-record-question/71299 "2006-10-06T19:16:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [October 6, 2006, 7:16pm UTC](https://www.ruby-forum.com/t/active-record-question/71299/1 "2006-10-06T19:16:45Z")

</div>

Sorry guys, I try and keep these sorts of questions to the Rails list  
but  
I’ve had little luck over there. Since this is a Ruby / Active Record  
question I thought I’d throw it out here.  
Apologies if it’s not appropriate.

Basically I have a form for the user to fill in. Within it are various  
select lists and those are set to multiple, so user can make multiple  
choices.  
I seem to be able to get them into the database using serialize() , but  
integers appear particularly funky with lots of hyphens and quotes. As  
well  
these values will be needed for queries and my understanding is that  
serialize is not the way to go.

So I wouldn’t mind some recommendations regarding options I might have  
to  
accomplish this feat, not including (more tables, if that’s possible).  
My initial thoughts and I haven’t tried it yet is perhaps using some  
type of  
regex to clean them up marshalling out , but not entirely sure if that  
makes  
sense.

TIA  
Stuart

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [October 6, 2006, 9:43pm UTC](https://www.ruby-forum.com/t/active-record-question/71299/2 "2006-10-06T21:43:27Z")

</div>

On 10/6/06, Jan S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > choices.  
> > type of  
> > read\_attribute(“length”) \* CU
> 
> Disclaimer: not tested, pure theory 😉
> 
> J.

I was wondering if there was a tried and true method. I’d imagine this  
is a  
fairly common thing with forms and databases.  
Stuart

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [October 6, 2006, 8:27pm UTC](https://www.ruby-forum.com/t/active-record-question/71299/3 "2006-10-06T20:27:22Z")

</div>

On 10/6/06, Dark A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> these values will be needed for queries and my understanding is that  
> serialize is not the way to go.
> 
> So I wouldn’t mind some recommendations regarding options I might have to  
> accomplish this feat, not including (more tables, if that’s possible).  
> My initial thoughts and I haven’t tried it yet is perhaps using some type of  
> regex to clean them up marshalling out , but not entirely sure if that makes  
> sense.

I suppose you can clean up the serialized form via custom attribute  
setters, getters (AWDwR page 284:)

class ProductData \< ActiveRecord::Base  
CU = 18  
def length  
read\_attribute(“length”) \* CU  
end

def lenght=(inches)  
write\_attribute(“length”, Float(inches) / CU)  
end  
end

Then it depends on what form is convenient for you and that depends on  
the data type and what you plan to do with the data (for example you  
could do array.map {|i| i.to\_s}.join(‘,’) for an array of integers)

Disclaimer: not tested, pure theory 😉

J.

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [October 7, 2006, 6:49am UTC](https://www.ruby-forum.com/t/active-record-question/71299/4 "2006-10-07T06:49:39Z")

</div>

The “tried and true” method I think you’re hinting at involves exactly  
what you’d like to avoid – more tables. The best way to represent  
data in a relational database is to, surprise, surprise, use relations.  
By storing more than one value in a single field you’re going to make  
it difficult for yourself in the future if you want to do any sort of  
meaningful queries on your data (esp if you have millions of records).

For example, if your database stores blog posts, and you want to enable  
categories to be assigned to every blog post, this requires 3 tables:

- A table that stores posts (eg, posts(id, text))
- A table that stores all the possible categories (eg, categories(id,  
name))
- A table that relates the two (eg, categories\_posts(category\_id,  
post\_id))

ActiveRecord supports this using the has\_many relationship with the  
:through attribute. All of the joins that would be required are taken  
care of for you, and you get things like:

post.categories \<\< Category.find\_by\_name(‘databases’)  
post.categories.delete(Category.find\_by\_name(‘databases’))

category.posts.each do |post|  
# … something  
end

This is WAY easier than the other option which is to have a category  
text field that you maintain yourself, but this causes a few problems  
for maintence:

- If you want to remove a category, you must loop through every post  
and do a string replace on the category text field.
- If you want to get all the posts in a given category, you have to  
write a LIKE query which can be imprecise unless you’re careful about  
how you format the field (eg, what do you do about categories that  
share the same suffix or prefix)
- It’s difficult to come up with a proper list of all possible  
categories – you have to loop through every post and parse the  
category field. You could keep this in a constant somewhere in your  
app, but keeping this list up to date is a maintenence nightmare and at  
that point you’ve made it difficult to add/remove categories on the fly  
without requiring knowledge of Ruby.
- etc, etc… have I made my point yet?

I’m not against storing multiple values in a single field – sometimes  
its the most practical and expedient method, especially if none of the  
above situations apply. However, if you’re looking for the “tried and  
true” (which I take to mean scalable and clean) method, something like  
the above is something you should consider.
