How do I get make the in_memory adapter of the the ruby library DataMapper to save the model's id properly?

StackOverflow https://stackoverflow.com/questions/688916

  •  22-08-2019
  •  | 
  •  

Question

This regards the ruby ORM library DataMapper.

This wiki describes how to use the in_memory adapter for DataMapper. The proper database adapters saves an incrementing, unique id on each model instance - in_memory doesn't seem to do that as shown by the following snippet:

require 'rubygems'
require 'dm-core'

DataMapper.setup(:in_memory, :adapter => 'in_memory')

class Foo
    include DataMapper::Resource

    def self.default_repository_name;:in_memory;end
    def self.auto_migrate_down!(rep);end
    def self.auto_migrate_up!(rep);end
    def self.auto_upgrade!(rep);end

    property :id, Serial
    property :name, Text
end

f = Foo.new
f.name = "foo"
f.save

puts f.inspect

The results of the inspect is:

#<Foo id=nil name="foo">

Had I used another adapter to connect to, for instance, a sqlite database id would've been set to '1'.

I would like to refer to my models via id, because I can't guarantee uniqueness on other attribuets. Is there a way of making the in_memory adapter save an incrementing, unique id attribute for its models?

Was it helpful?

Solution

As far as I can tell, auto-incrementing is not supported for the DM in-memory adapter (I suspect that adapter doesn't get much love) but you could fake it pretty easily:

before :save, :increment_id
def increment_id
  self.id ||= begin
    last_foo = (Foo.all.sort_by { |r| r.id }).last
    (last_foo ? last_foo.id : 0).succ
  end
end

I don't think I'd recommend this though. One probably much better alternative would be to use a SQLite in-memory database instead.

OTHER TIPS

Not sure what your exact issue was, but this issue is now fixed - your example script works with DataMapper 1.0.2. Further, the correct syntax now is:

require 'dm-core'

DataMapper.setup(:default, :adapter => 'in_memory')

class Foo
  include DataMapper::Resource

  property :id, Serial
  property :name, Text
end

f = Foo.new
f.name = "foo"
f.save

puts f.inspect

Contrary to Bob's answer, the in-memory adapter is a first class citizen that is kept up to date and documented, because it is used extensively in the test suite, and also provided as an example base for new adapters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top