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

version.next returns same version #317

Closed
bigglesrocks opened this issue Jan 14, 2014 · 15 comments
Closed

version.next returns same version #317

bigglesrocks opened this issue Jan 14, 2014 · 15 comments
Assignees
Milestone

Comments

@bigglesrocks
Copy link

If I have a widget with 15 versions, and I have version 12, I run the following:

version.index    # returns 12
version.previous.index    # returns 11
version.next.index    # returns 12, NOT 13 as expected

The same behavior happens with widget.next_version as well.

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

Can you provide some more information please? (PaperTrail version / ActiveRecord version, etc.) What type of database are you using? This could be related to #314 if you are seeing this in testing?

@bigglesrocks
Copy link
Author

Ruby 2.0.0p247
Rails 4
SQLite
PaperTrail v 3.0.0
ActiveRecord 4.0.1
Rspec Rails 2.14.0

I did read over #314, however the issue is not manifesting in testing, but in development.

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

Can you print the return results from this in the console please?

> version
> version.sibling_versions
> version.sibling_versions.subsequent(version)
> version.sibling_versions.map { |v| p [v.id, v.send(PaperTrail.timestamp_field)] }
# this reloads the association
> version.sibling_versions(true)
> version.sibling_versions.subsequent(version)
> version.sibling_versions.map { |v| p [v.id, v.send(PaperTrail.timestamp_field)] }

@bigglesrocks
Copy link
Author

I can provide a yaml formatted dump, if needed, but it's quite long.

version

=> #<PaperTrail::Version id: 985, item_type: "Project", item_id: 202, event: "update", whodunnit: "18", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: I...", created_at: "2014-01-13 19:27:48", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">

version.sibling_versions

 => #<ActiveRecord::Relation [#<PaperTrail::Version id: 956, item_type: "Project", item_id: 202, event: "create", whodunnit: "4", object: nil, created_at: "2014-01-08 21:38:31", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 957, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Title\ncomment: Add a comment\n...", created_at: "2014-01-08 21:39:18", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 961, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:28:36", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 962, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:30:24", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 963, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:30:30", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 964, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:35:19", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 965, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:35:23", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 966, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:36:19", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 975, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-10 21:07:00", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 980, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-10 22:17:51", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, ...]>

version.sibling_versions.subsequent(version)

  PaperTrail::Version Load (0.3ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 AND (created_at > '2014-01-13 19:27:48.000000') ORDER BY created_at ASC
 => #<ActiveRecord::Relation [#<PaperTrail::Version id: 985, item_type: "Project", item_id: 202, event: "update", whodunnit: "18", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: I...", created_at: "2014-01-13 19:27:48", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 986, item_type: "Project", item_id: 202, event: "update", whodunnit: "18", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: I...", created_at: "2014-01-13 19:29:00", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 987, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: '...", created_at: "2014-01-13 21:34:46", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 988, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: '...", created_at: "2014-01-13 21:35:00", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">]>

version.sibling_versions.map { |v| p [v.id, v.send(PaperTrail.timestamp_field)] }

[956, Wed, 08 Jan 2014 21:38:31 UTC +00:00]
[957, Wed, 08 Jan 2014 21:39:18 UTC +00:00]
[961, Wed, 08 Jan 2014 22:28:36 UTC +00:00]
[962, Wed, 08 Jan 2014 22:30:24 UTC +00:00]
[963, Wed, 08 Jan 2014 22:30:30 UTC +00:00]
[964, Wed, 08 Jan 2014 22:35:19 UTC +00:00]
[965, Wed, 08 Jan 2014 22:35:23 UTC +00:00]
[966, Wed, 08 Jan 2014 22:36:19 UTC +00:00]
[975, Fri, 10 Jan 2014 21:07:00 UTC +00:00]
[980, Fri, 10 Jan 2014 22:17:51 UTC +00:00]
[981, Fri, 10 Jan 2014 22:21:04 UTC +00:00]
[984, Mon, 13 Jan 2014 19:25:44 UTC +00:00]
[985, Mon, 13 Jan 2014 19:27:48 UTC +00:00]
[986, Mon, 13 Jan 2014 19:29:00 UTC +00:00]
[987, Mon, 13 Jan 2014 21:34:46 UTC +00:00]
[988, Mon, 13 Jan 2014 21:35:00 UTC +00:00]

version.sibling_versions(true)

 PaperTrail::Version Load (0.4ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202
 => #<ActiveRecord::Relation [#<PaperTrail::Version id: 956, item_type: "Project", item_id: 202, event: "create", whodunnit: "4", object: nil, created_at: "2014-01-08 21:38:31", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 957, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Title\ncomment: Add a comment\n...", created_at: "2014-01-08 21:39:18", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 961, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:28:36", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 962, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:30:24", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 963, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:30:30", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 964, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:35:19", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 965, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:35:23", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 966, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-08 22:36:19", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 975, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-10 21:07:00", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 980, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: A...", created_at: "2014-01-10 22:17:51", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, ...]>

version.sibling_versions.subsequent(version)

  PaperTrail::Version Load (0.4ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 AND (created_at > '2014-01-13 19:27:48.000000') ORDER BY created_at ASC
 => #<ActiveRecord::Relation [#<PaperTrail::Version id: 985, item_type: "Project", item_id: 202, event: "update", whodunnit: "18", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: I...", created_at: "2014-01-13 19:27:48", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 986, item_type: "Project", item_id: 202, event: "update", whodunnit: "18", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: I...", created_at: "2014-01-13 19:29:00", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 987, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: '...", created_at: "2014-01-13 21:34:46", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">, #<PaperTrail::Version id: 988, item_type: "Project", item_id: 202, event: "update", whodunnit: "4", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: '...", created_at: "2014-01-13 21:35:00", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">]>

version.sibling_versions.map { |v| p [v.id, v.send(PaperTrail.timestamp_field)] }

[956, Wed, 08 Jan 2014 21:38:31 UTC +00:00]
[957, Wed, 08 Jan 2014 21:39:18 UTC +00:00]
[961, Wed, 08 Jan 2014 22:28:36 UTC +00:00]
[962, Wed, 08 Jan 2014 22:30:24 UTC +00:00]
[963, Wed, 08 Jan 2014 22:30:30 UTC +00:00]
[964, Wed, 08 Jan 2014 22:35:19 UTC +00:00]
[965, Wed, 08 Jan 2014 22:35:23 UTC +00:00]
[966, Wed, 08 Jan 2014 22:36:19 UTC +00:00]
[975, Fri, 10 Jan 2014 21:07:00 UTC +00:00]
[980, Fri, 10 Jan 2014 22:17:51 UTC +00:00]
[981, Fri, 10 Jan 2014 22:21:04 UTC +00:00]
[984, Mon, 13 Jan 2014 19:25:44 UTC +00:00]
[985, Mon, 13 Jan 2014 19:27:48 UTC +00:00]
[986, Mon, 13 Jan 2014 19:29:00 UTC +00:00]
[987, Mon, 13 Jan 2014 21:34:46 UTC +00:00]
[988, Mon, 13 Jan 2014 21:35:00 UTC +00:00]

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

Thanks for the report, looks like the timestamps are definitely not the issue. Is there an easy way you can print out the SQL that is reported from the original syntax in your issue report?

# Each of these should print out SQL in the console the first time you access the `index` for it
version = PaperTrail::Version.find(985)
version.index    # returns 12
version.previous.index    # returns 11
version.next.index    # returns 12, NOT 13 as expected

@bigglesrocks
Copy link
Author

version = PaperTrail::Version.find(985)

PaperTrail::Version Load (0.2ms)  SELECT "versions".* FROM "versions" WHERE "versions"."id" = ? LIMIT 1  [["id", 985]]

version.index

 PaperTrail::Version Load (0.2ms)  SELECT created_at, id FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 ORDER BY created_at ASC
 => 12

version.previous.index

 PaperTrail::Version Load (0.3ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 AND (created_at < '2014-01-13 19:27:48.000000') ORDER BY created_at DESC LIMIT 1
  PaperTrail::Version Load (0.1ms)  SELECT created_at, id FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 ORDER BY created_at ASC
 => 11

version.next.index

  PaperTrail::Version Load (0.3ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 AND (created_at > '2014-01-13 19:27:48.000000') ORDER BY created_at ASC LIMIT 1
  PaperTrail::Version Load (0.2ms)  SELECT created_at, id FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 ORDER BY created_at ASC
 => 12

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

That being said, it looks like it may be an issue of Timestamp.

Let's look at the SQL being executed for version.next (which invokes version.sibling_versions.subsequent(version))

PaperTrail::Version Load (0.4ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 AND (created_at > '2014-01-13 19:27:48.000000') ORDER BY created_at ASC

So it is looking for the first entry in the versions table where item_id = 202 and created_at > '2014-01-13 19:27:48.000000'. I'm guessing if you invoke PaperTrail::Version.find(985).created_at.usec (which returns the microseconds for the timestamp object), it is not 000000, which explains why it is returning itself for that query. If this is the case, then the question is why it isn't properly passing in the microseconds to the query, because it is on my local test ENV (which is also using SQLite).

@bigglesrocks
Copy link
Author

I did a short test in the production environment which is running Postgres on Heroku and version.next & version.previous both behave as expected.

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

I'm looking at rails/rails#10855 and wondering if that could be related. What happens if you print out:

> version = PaperTrail::Version.find(985)
> version.created_at.usec
> version.created_at.nsec
> version.created_at_before_type_cast

@bigglesrocks
Copy link
Author

version = PaperTrail::Version.find(985) returns

PaperTrail::Version Load (0.2ms)  SELECT "versions".* FROM "versions" WHERE "versions"."id" = ? LIMIT 1  [["id", 985]]
 => #<PaperTrail::Version id: 985, item_type: "Project", item_id: 202, event: "update", whodunnit: "18", object: "---\nid: 202\nname: Add Char/Number limits\ncomment: I...", created_at: "2014-01-13 19:27:48", object_changes: "--- !ruby/hash:ActiveSupport::HashWithIndifferentAc...">

version.created_at returns 0 using both usec and nsec methods.

version.created_at_before_type_cast returns

"2014-01-13 19:27:48.150878"

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

Whoops, sorry corrected my comment above. But anyways that seems to explain what the issue is. The microseconds / milliseconds not being passed into the query for some reason.

@bigglesrocks
Copy link
Author

Does it seem odd that version.previous is not affected in the same way as version.next?

for version 985

> version.next
PaperTrail::Version Load (0.3ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 AND (created_at > '2014-01-13 19:27:48.000000') ORDER BY created_at ASC LIMIT 1
=> #<PaperTrail::Version id: 985...
> version.previous
PaperTrail::Version Load (0.3ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_type" = 'Project' AND "versions"."item_id" = 202 AND (created_at < '2014-01-13 19:27:48.000000') ORDER BY created_at DESC LIMIT 1
=> #<PaperTrail::Version id: 984...

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

No. Because version.created_at_before_type_cast is 2014-01-13 19:27:48.150878, which is the first version in the database where created_at > '2014-01-13 19:27:48.000000'. The first version in the database where created_at < '2014-01-13 19:27:48.000000' is indeed the previous one.

When you invoke version.next, the query should have this criteria created_at > '2014-01-13 19:27:48.150878' when it is working correctly. That is how it works on my local at least. So it appears as though this may be a third party issue, but I'm having difficulty pinning down what the issue is exactly. Can you try upgrading to Rails to 4.0.2? What version of the Sqlite3 gem are you using? (I have 1.3.8 on my local)

@batter
Copy link
Collaborator

batter commented Jan 14, 2014

Ok kept digging into this and found rails/rails#12422 which seems similar. I have to think this is a third party issue of sorts because I can't reproduce it, and if it was a problem with the PaperTrail code I'm pretty sure our automated test suite would have caught it.

@bigglesrocks
Copy link
Author

Hmm, that does appear to be the issue I'm having.

I don't want to upgrade my current application to 4.0.2 at the moment, but I'm creating a barebones app and model with has_paper_trail to see if the Ruby version is indeed the issue.

@ghost ghost assigned batter Jan 21, 2014
batter added a commit that referenced this issue Apr 1, 2014
…rn if primary key is an integer.

This makes some of the changes to these scope methods that came from 6a4aba2 more flexible,
in that the user can choose to compare timestamps if desired, but it defaults to comparing and sorting,
via the primary key (if it is an integer).  If the primary key is not an integer, it still defaults
to using the PaperTrail.timestamp_field.

This is my proposed fix for #314, and I also believe it should fix #317. It seems that that this issue
is usually encountered when testing PaperTrail with MySQL (presumably due to lack of microsecond timestamp support).
@batter batter added this to the 3.0.2 milestone Apr 16, 2014
@batter batter closed this as completed in 1a13748 May 9, 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

2 participants