Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restore method possible? #333

Closed
nicolasfranck opened this issue Feb 21, 2014 · 26 comments
Closed

restore method possible? #333

nicolasfranck opened this issue Feb 21, 2014 · 26 comments
Assignees

Comments

@nicolasfranck
Copy link

As I understand the method

version.reify

restores the state of the object PRIOR to this version,
and so undoing changes made by this version. And
that's why versions with event "create" cannot do anything
usefull.

But I think it would be nice to have a method "restore",
that restores the object to the version itself, instead
of its prior version.

@batter batter self-assigned this Feb 21, 2014
@batter
Copy link
Collaborator

batter commented Feb 21, 2014

Sorry, I'm not sure I understand your request entirely. As stated on this section of the README, you can revert the current object to the state of a prior version by doing something like this:

version.reify.save!

Are you just asking if we can put a method on PaperTrail::Version class that invokes that in one call? Something like this?

# Same thing as `version.reify.save!`
version.restore! # returns the live object as it has been restored

@nicolasfranck
Copy link
Author

No

Say you list all the versions in a table, and add a button next to it with text "restore".

version 2 => (last version)
version 1 => restore

Then you expect the restore of version 1 to reset all attributes to the first version,
thus doing something like this

PaperTrail::Version.find(1).next.reify.save!

@batter
Copy link
Collaborator

batter commented Feb 21, 2014

I think it would add some confusion, since it goes against the principles of how PaperTrail stores versions (as in it stores the state of the model as it is at that point in time). I think the API allows someone who wants to do something like that the ability pretty easily, but having restore! load the successive version seems misleading to me.

If anyone else wants to chime in, would love to hear other peoples thoughts on this.

If you want to do something like that in your usage of PaperTrail, I encourage you to add that model to your classes, or even clone the gem and add it to the PaperTrail::Model::InstanceMethods.

@nicolasfranck
Copy link
Author

Using papertrail from the tracked model itself, it works as I expected:

lib = Library.find(1)
lib.previous_version

But from the array "versions" it becomes confusing:

lib.versions.last.reify

gives you the previous version, not the last - i.e. current - version?
Or is this intended? Because the current version is already stored?

@OssieHirst
Copy link

This is exactly the problem I'm searching for a solution to. I have listed out the history of my Lines model using Paper_trail.

I have a table in my view something like:

User, event, changeset, time_ago_in_words, Revert

and I want the revert button to reload THAT version as displayed in it's changeset. Currently it undoes the changes that that version made.

I'm using Ryan Bates's undo code as the basis and have

<%= link_to("Revert", revert_version_path(version), :method => :post) %>

I had hoped that adding NEXT would give me the result I want:

<%= link_to("Revert", revert_version_path(version.next), :method => :post) %>

but that has no effect.

I realise this is not how paper_trail is intended to function but it is the function I am trying to implement and it seems to me that it could do it, I just don't know how.

Any idea?

@batter
Copy link
Collaborator

batter commented Apr 24, 2014

As @nicolasfranck stated in his original post, a version stores the state of an object PRIOR to the event that triggered the generation of the version. So if you want to load the object at the state it looked like AFTER version generation. @WorldOfProper, I think your implementation should work fine except for in cases where the version object is the last version for an object (i.e. version.next => nil).

There are a couple ways you could handle this scenario. The easiest thing I can think of is just putting the link inside of a conditional block on your view file, like so:

<% if version.next %>
  <%= link_to("Revert", revert_version_path(version.next), :method => :post) %>
<% end %>

That way, you will never run into the scenario where you are passing nil into the param. Hope that makes sense and solves your issue.

@OssieHirst
Copy link

It doesn't work though. That's the problem. revert_version_path(version.next) links to http://localhost:3000/versions/89/revert just like revert_version_path(version) does. The behaviour doesn't change at all when adding next in this case. Is there any other way of getting to the next version?

@OssieHirst
Copy link

In fact calling <%= version.next.id %> gives the same result as <%= version.id %>.

version.previous works as expected. Is this a bug in the gem? I can't quite see how I can have created this problem in my installation?

@craigsheen
Copy link

Isn't that because the version won't have a next and therefore it just returns the, I"m guessing, last version (which will therefore be version).

@OssieHirst
Copy link

Why won't it have a next? I've just created a new object, then updated it five times. I have 5 versions, all with version ids. In what way do they not have nexts?

@OssieHirst
Copy link

This line
Version = <%= version.id %> Prev = <% if version.previous %><%= version.previous.id %><% end %> Next = <% if version.next %><%= version.next.id %><% end %>

Returns this
Version = 146 Prev = 145 Next = 146

@craigsheen
Copy link

Surely that depends on what version is set to in your previous example?

If you have the version (Model.first.versions.last) and do version.next it would return the same version, that's all I meant.

@OssieHirst
Copy link

It's in an each do block so there will be first, last and all the ones in between. None of which show a different id for version.next.

@craigsheen
Copy link

Ah actually, checking you do have a point. My appologies, I see what you mean.

Product.first.versions.each do |v|
  puts "id: #{v.id} .. Next id:#{v.next.id}"
end
=>
id: 3 .. Next id:3
id: 4 .. Next id:4
id: 5 .. Next id:5

@OssieHirst
Copy link

That's good to know. I'll stop trying to search for my mistake for a bit :)

@craigsheen
Copy link

Just did a bit of digging on this. What seems to be happening is when you do next. It gathers the versions, finds the versions that are greater than the current versions created_at then selects the first one.

Now the issue is that when it does that the the current version is actually appearing in the results. As below;

Product.first.versions.first
 => #<PaperTrail::Version id: 3, item_type: "Product", item_id: 3, event: "create", whodunnit: nil, object: nil, created_at: "2014-04-24 15:41:29", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc..."> 

c = Product.first.versions.first.send(PaperTrail.timestamp_field)

Product.first.versions.where("created_at > ?", c)
=> #<ActiveRecord::AssociationRelation [#<PaperTrail::Version id: 3, item_type: "Product", item_id: 3, event: "create", whodunnit: nil, object: nil, created_at: "2014-04-24 15:41:29", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 4, item_type: "Product", item_id: 3, event: "update", whodunnit: nil, object: "---\nid: 3\nname: something\ntype: Foobar\nrole: \ncreat...", created_at: "2014-04-25 13:52:24", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 5, item_type: "Product", item_id: 3, event: "update", whodunnit: nil, object: "---\nid: 3\nname: blah\ntype: Foobar\nrole: \ncreated_at...", created_at: "2014-04-25 13:52:36", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">]> 

# Notice how the first version is included in this when it shouldn't be

Product.first.versions.where("created_at > ?", c+1.second)
 => #<ActiveRecord::AssociationRelation [#<PaperTrail::Version id: 4, item_type: "Product", item_id: 3, event: "update", whodunnit: nil, object: "---\nid: 3\nname: something\ntype: Foobar\nrole: \ncreat...", created_at: "2014-04-25 13:52:24", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 5, item_type: "Product", item_id: 3, event: "update", whodunnit: nil, object: "---\nid: 3\nname: blah\ntype: Foobar\nrole: \ncreated_at...", created_at: "2014-04-25 13:52:36", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">]>

# This is now correct as it does not include the current version

@OssieHirst
Copy link

So version.next is broken?

@batter
Copy link
Collaborator

batter commented Apr 25, 2014

I suspect this is the same as #314. Please try the branch order_by_primary_key, it will likely solve your issues. Been super busy this week but am going to try to merge it next week.

I'm guessing you're doing your updates in a block (in testing or not), and they are all getting fired simultaneously (virutally), and so the millisecond timestamp support, or lack thereof, is likely the real culprit here.

@OssieHirst
Copy link

Great. I'll try the branch when I get a second.

@OssieHirst
Copy link

That solved it. Thank you. Now working as intended.

@OssieHirst
Copy link

Agh! Panic. I find that order_by_primary_key branch is no longer working so I assumed it had been merged but when I bundle the current version my site doesn't work.

Spent the last three weeks working on paper_trail but now it appears to be kaput.

Any idea what I can do? Neither the branch version nor the current version support version.next

Very scared.

@OssieHirst
Copy link

I see that the branch is gone. I had that branch working perfectly after weeks of work but the master is not exhibiting the behaviour that the branch did.

<%= version.id %> and <%= version.next.id %> are back to showing the same number.

@batter
Copy link
Collaborator

batter commented May 27, 2014

@WorldOfProper - I merged order_by_primary_key into the master branch. It is part of the 3.0.2 release so you can upgrade to that version of the gem and you should be good to go.

1a13748 is likely the last commit that was made before I did some finishing touches and merged that branch on May 9th... I was under the impression that everything was working as expected now. You're still seeing issues?

@OssieHirst
Copy link

Sorry I can't test it as I stupidly ran bundle update rather than just updating paper_trail. I now have a non-functioning app and am trying to retrace my steps. I can't test 3.0.2 until I can get my app to run again. Oh boy.

@OssieHirst
Copy link

Ok, got my app running again. What an idiot.

Updated to 3.0.2 and it's working a treat. This gem is so important to the functioning of my site. I can't thank you enough for your work and your patience with idiots like me.

@batter
Copy link
Collaborator

batter commented May 30, 2014

No worries, happy to hear that 3.0.2 fixed the issues. That was the primary thing I was targeting in that release.

@batter batter closed this as completed Oct 24, 2014
@batter batter removed the Not a bug label Oct 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants