rubyruby-datamapper

Updating a property set as the key in DataMapper


Is it possible to update a property in DataMapper if :key is set to true?

Say, for example, I have a model set up like this:

class Post
  include DataMapper::Resource
  property :slug, Text, :unique => true, :key => true
  # ...
end

and I made a new instance of this with :slug => "example-post-title".

I tried to update it by accessing the stored

@post = Post.get("example-post-title")
#=> #<Post @slug="example-post-title" ...>
@post.slug = "example-post-title-2"
#=> "example-post-title-2"
@post.save
#=> true
@post = Post.get("example-post-title-2")
#=> nil

but as you can see the slug was never updated. I also tried using the Post#update method:

@post = Post.get("example-post-title")
#=> #<Post @slug="example-post-title" ...>
@post.update(:slug => "example-post-title-2")
#=> true
@post = Post.get("example-post-title-2")
#=> nil

Looking in the database, the index column is not changed by either of these examples. It remains as example-post-title rather than example-post-title-2.

According to the docs, the Post#update method, similar to the Post#save method, should return true if the operation was successful, and false if it was not. It is returning true here, but it's not actually updating the record.

I've searched and searched and can't find anything about it on the Internet. Neither StackOverflow nor the DataMapper rdoc had anything about updating the key.

I know that I can have a unique Serial property and just get instances of Post using the slug (as in, make the Serial property the key instead of the slug), but I'm looking for a way to do it without that, if at all possible.


Solution

  • My hunch is that you can't update a key. According to the doc, they are protected against mass assignment:

    Natural Keys are protected against mass-assignment, so their setter= will need to be called individually if you're looking to set them.

    They don't talk about updating them but usually in "key => value" stores it is impossible or deprecated to update the key. I'd assume that's the case here as well, even though I can't find any hard evidence to give to you : /