1

I'm getting started with Ruby and DataMapper and I stumbled upon a problem which I think does not make any sense. Let's say I have the following model :

class Foo
  include DataMapper::Resource

  property :id, Serial
  property :date, Date, required: true

  def initialize
    @date = Date.today
  end
end

I open up IRB to test my models, set up the database connection, and try to save a new foo:

> foo = Foo.new
> foo.date
=> #<Date: 2013-03-28 ((2456380j,0s,0n),+0s,2299161j)>
> foo.save

Then I get the following exception :

DataObjects::IntegrityError: foos.date may not be NULL

And that perfectly makes sense, because I marked the date as required. But the date is there! I assigned it in the constructor of the class! And if I don't initialize it with today's date and I try to save, I only get a validation error. No exception.

What I don't understand (and this is what I want you to answer to) is that if I replace

@date = Date.today

with

self.date = Date.today

it works! foo is saved correctly. Why is that? Is it a bug inside DataMapper?

marco-fiset
  • 1,933
  • 1
  • 19
  • 31
  • This means that DataMapper keeps some sort of internal set/not set data structure which is only manipulated when you use their setters/getters and not the underlying variable. – Linuxios Mar 28 '13 at 15:50
  • @Linuxios: And is there a way to make it work the logical way? It is very counter intuitive the way it works currently. – marco-fiset Mar 28 '13 at 15:52
  • 1
    Do exactly what you said and use `self.date`. Instance variables are the most internal part of a class -- if you use them to interact with DataMapper's internals, your messing with fire. – Linuxios Mar 28 '13 at 15:54
  • @Linuxios I'm not trying to interact with DataMapper's internals, I only want to set a property on my object. I might be picky, but I find it cumbersome to rewrite every assignment to `self.` instead of `@` just to be sure that my properties are persisted to the database. – marco-fiset Mar 28 '13 at 15:58
  • It is cumbersome, but necessary. The people who wrote DataMapper could make it possible, but you have to take that up with them. – Linuxios Mar 28 '13 at 15:59

1 Answers1

1

After bringing up the issue with DataMapper's people, I've been told that this is by design. For dirty tracking to work, you must absolutely use the attribute writer and not set the instance variable directly.

marco-fiset
  • 1,933
  • 1
  • 19
  • 31