I'm interested in storing multiple values in a single column, rather than use the traditional many-to-many table:
class Beer
include DataMapper::Resource
property :id, Serial
property :name, String
property :containers, Integer # use bit arithmetic to store multiple values
validates_presence_of :name, :containers
end
class Container
include DataMapper::Resource
property :id, Serial # increment in powers of two?
property :name, String
property :volume, Integer
validates_presence_of :name, :volume
end
Containers:
ID Name Volume Unit
1 Growler 64 oz
2 Cowler 32 oz
4 Bomber 750 mL
8 Six-fifty 650 mL
16 4 pack 64 oz
32 6 pack 72 oz
Beers:
ID Name Containers
1 LSD 72
2 Düo 16
Is there an easy way to configure a DataMapper resource to increment serial values in powers of 2? I'm assuming that the association is going to be a challenge.
You can't do that with Serial
property type, but you can use an Integer and a before :create
hook:
class Container
include DataMapper::Resource
property :id, Integer, key: true # Use whatever options you like
property :name, String
property :volume, Integer
validates_presence_of :name, :volume
# Create a new id based on the last element
before :create do |c|
last_container = Container.last
# If integer has N bits, then you can only store N containers in your database (normally, 32 or 64 bits).
c.id = last_container ? (last_container.id * 2) : 1
end
end
Anyways, you should be using the relational model, instead of using this hacky-tricks, as someone already commented on your post. It's much more maintainable, easy to read and simple than this kind of solutions.
Oh, by the way, if you need fast access to your database, you should check a look at Graph databases and neo4jrb, an OGM for Neo4j.