Updating parent resource whenever child is updated


#1

I have nested resources as follows: ‘albums has_many photos’.
Whenever someone edits photos, I would like update time stamp on albums.
I tried to do this like:
@photos.albums.updated_by = @currentusername
@photos.albums.save

But, this is not updating albums. I don’t see anything happening in the
database log or mongrel log.

CS.


#2

I think the new functionality in edge rails will do what you want:

http://afreshcup.com/2009/04/19/touch-your-active-record-instances/

You say:

class Photo
belongs_to :user, :touch => true
end

This way, whenever you save or delete a photo instance, it’ll ‘touch’
its parent user, and update the updated_at timestamp.

This will require you to upgrade to edge rails, though.

Looking at your attempt, though, I’m not sure this is what you want. Are
you also using the “updated_by” attribute of the photo to save the id of
the user that changed it?

Chris

Carlos S. wrote:

I have nested resources as follows: ‘albums has_many photos’.
Whenever someone edits photos, I would like update time stamp on albums.
I tried to do this like:
@photos.albums.updated_by = @currentusername
@photos.albums.save

But, this is not updating albums. I don’t see anything happening in the
database log or mongrel log.

CS.


#3

Thanks Chris.
I am using created_at and updated_at attributes for timestamps. For
getting user info. though, I have creuser and upduser attributes.

Is there any other way to do this other than upgrading it to edge rails?

Thanks,
CS.

Chris H. wrote:

I think the new functionality in edge rails will do what you want:

http://afreshcup.com/2009/04/19/touch-your-active-record-instances/

You say:

class Photo
belongs_to :user, :touch => true
end

This way, whenever you save or delete a photo instance, it’ll ‘touch’
its parent user, and update the updated_at timestamp.

This will require you to upgrade to edge rails, though.

Looking at your attempt, though, I’m not sure this is what you want. Are
you also using the “updated_by” attribute of the photo to save the id of
the user that changed it?

Chris

Carlos S. wrote:

I have nested resources as follows: ‘albums has_many photos’.
Whenever someone edits photos, I would like update time stamp on albums.
I tried to do this like:
@photos.albums.updated_by = @currentusername
@photos.albums.save

But, this is not updating albums. I don’t see anything happening in the
database log or mongrel log.

CS.


#4

Well, the updated_at timestamp for the album should update automatically
to the current time whenever the album model is changed and saved, so if
you’re trying to do that then you don’t need to use touching.

I’m confused at how your app is set up - if album has_many photos and
photo belongs_to album, then shouldn’t your photo saving method use
singular objects? As in:

@photo.album.updated_by = @currentusername
@photo.album.save

That is, assuming you’ve defined “updated_by” in your migration as a
string to save the name of the current user - I think that’s what you’re
going for.

What I would do next is put debugger right between those two lines, then
call the save as a bang method (@photo.album.save!) and see what error
you get (if any).

Chris

Carlos S. wrote:

Thanks Chris.
I am using created_at and updated_at attributes for timestamps. For
getting user info. though, I have creuser and upduser attributes.

Is there any other way to do this other than upgrading it to edge rails?

Thanks,
CS.

Chris H. wrote:

I think the new functionality in edge rails will do what you want:

http://afreshcup.com/2009/04/19/touch-your-active-record-instances/

You say:

class Photo
belongs_to :user, :touch => true
end

This way, whenever you save or delete a photo instance, it’ll ‘touch’
its parent user, and update the updated_at timestamp.

This will require you to upgrade to edge rails, though.

Looking at your attempt, though, I’m not sure this is what you want. Are
you also using the “updated_by” attribute of the photo to save the id of
the user that changed it?

Chris

Carlos S. wrote:

I have nested resources as follows: ‘albums has_many photos’.
Whenever someone edits photos, I would like update time stamp on albums.
I tried to do this like:
@photos.albums.updated_by = @currentusername
@photos.albums.save

But, this is not updating albums. I don’t see anything happening in the
database log or mongrel log.

CS.


#5

Because the upduser is the same, it doesn’t think that the object has
really changed, so doesn’t update the timestamps.

We had a similar problem where we needed to update the timestamps on the
root object of a tree whenever anything in the tree changed. I ended up
implementing a touch method on the object, and called that in a
before_save hook.

def touch
orig_title = self.title
self.title = ’ ’
self.title = orig_title
self.save
end

def after_save_hook
root.touch
true
end

the edge rails code looks much nicer, but it will be a while before we
can move to newer rails.

Simon


#6

Thats weired…
I would expect parent.save to return false then… :frowning:

Thanks for the help.

CS.

Simon M. wrote:

Because the upduser is the same, it doesn’t think that the object has
really changed, so doesn’t update the timestamps.

We had a similar problem where we needed to update the timestamps on the
root object of a tree whenever anything in the tree changed. I ended up
implementing a touch method on the object, and called that in a
before_save hook.

def touch
orig_title = self.title
self.title = ’ ’
self.title = orig_title
self.save
end

def after_save_hook
root.touch
true
end

the edge rails code looks much nicer, but it will be a while before we
can move to newer rails.

Simon


#7

It uses singular objects. I am sorry I typed it wrongly over here.

I tried to debug it using console. My observation was if:
@photo.album.upduser = @currentuser is same as previous user then
timestamps are not getting changes. However, @photo.album.save works and
returns true.

Any clues?

Thanks,
CS.

Chris H. wrote:

Well, the updated_at timestamp for the album should update automatically
to the current time whenever the album model is changed and saved, so if
you’re trying to do that then you don’t need to use touching.

I’m confused at how your app is set up - if album has_many photos and
photo belongs_to album, then shouldn’t your photo saving method use
singular objects? As in:

@photo.album.updated_by = @currentusername
@photo.album.save

That is, assuming you’ve defined “updated_by” in your migration as a
string to save the name of the current user - I think that’s what you’re
going for.

What I would do next is put debugger right between those two lines, then
call the save as a bang method (@photo.album.save!) and see what error
you get (if any).

Chris