A way to `touch` date keys, ActiveRecord-style

已查看 22 次
跳至第一个未读帖子

Jérémy Lecour

未读,
2011年5月23日 07:14:072011/5/23
收件人 MongoMapper
Hi

I needed to update a Date key in a document, just like we can do with
ActiveRecord::Base#touch.

Here is my first try with a plugin : https://gist.github.com/986555

What do you think ?

Jeremy

Kevin Lawver

未读,
2011年5月23日 07:19:522011/5/23
收件人 mongo...@googlegroups.com
I wouldn't drop to the driver unless you have to (and in this case, you don't):

def touch(key = :updated_at)
raise "InvalidKey" unless self.key_names.include?(key.to_s)
self.set(key => Time.now)
true
end

It's shorter and you don't have to worry about upserts since MongoMapper should take care of that for you.  I'd keep the check for the key name because Mongo will just go and let you set any old random key and won't complain.

Kevin

Jérémy Lecour

未读,
2011年5月23日 07:33:102011/5/23
收件人 MongoMapper
Hi Kevin,

Thanks for the quick answer.

Using the MM API seems to be better to update the current object's
key.

I'm not yet really familiar with this API, but I wonder ; does it
update the DB (or just the object's value)? If yes, does it save only
this key, or the entire Document?

That's what interested me in the 1st place. I want to be able to
update just this key on a fairly large document, without overwriting
the whole document. It's not for performance reasons. There are
possible race conditions ; parts of the document will be updated by
many workers around the same time and I don't want to put locks on the
document. That's one of the reasons I've decided to use Mongo instead
of MySQL.

About dropping to the driver or not is something I've been wondering
about for different needs. I've looked for a way to update only
certain keys of documents, but it seems that MM doesn't allow that, it
updates the whole document. If there is a way, I'd be happy to know
it.

Thanks again for your knowledge ;-)

Kevin Lawver

未读,
2011年5月23日 07:41:272011/5/23
收件人 mongo...@googlegroups.com
.set does what you're looking for (I use it all the time).  It does exactly what you're doing in the driver but if you stay inside MongoMapper you don't have to worry about updating your plugin in the future if the underlying call changes (I recently moved all my direct-to-driver calls except one to the MongoMapper version and haven't had any issues).  It only updates the field in the database - it doesn't even update the object you're working on - which could be a problem if you go back and call save on it later.  You might want to add something like self[key] = Time.now to it so you keep the same value in the current object as well.

add_to_set, push and pull all work the same way, so you either need to reload the document to see the changes, or update them in both places (I waffle between which is the better choice, but usually opt to change them in both places just in case).

Jérémy Lecour

未读,
2011年5月23日 07:45:142011/5/23
收件人 MongoMapper
That's great, thanks.

On 23 mai, 13:41, Kevin Lawver <ke...@lawver.net> wrote:
>  .set does what you're looking for (I use it all the time). It does exactly what you're doing in the driver but if you stay inside MongoMapper you don't have to worry about updating your plugin in the future if the underlying call changes (I recently moved all my direct-to-driver calls except one to the MongoMapper version and haven't had any issues). It only updates the field in the database - it doesn't even update the object you're working on - which could be a problem if you go back and call save on it later. You might want to add something like self[key] = Time.now to it so you keep the same value in the current object as well.
>
回复全部
回复作者
转发
0 个新帖子