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.
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 : /