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.
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)
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:
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.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.