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

Usage with Friendly ID #428

Closed
simonmorley opened this issue Sep 30, 2014 · 22 comments
Closed

Usage with Friendly ID #428

simonmorley opened this issue Sep 30, 2014 · 22 comments
Milestone

Comments

@simonmorley
Copy link

I've been using this in a Rails 4.1.4 app with friendly_id for a while and have just noticed that my friendly id slug is not persisted in the object when a version is created.

Temporarily, I tested by added attr_accessor :slug which stores it but can't do that long-term.

Am using alongside:

has_paper_trail only: [:slug, :other, :attributes]

Have tested removing this and with ignore, skip etc.

Each time I rollback to a previous version, I lost the slug which is obviously a significant issue. Is there anything you can see which might cause this?

@batter
Copy link
Collaborator

batter commented Oct 1, 2014

Sorry, I'm having trouble understanding what the issue is, can you provide some more details. Ideally, utilize the ActiveRecord template for gems to give me something to reproduce your issue with?

@simonmorley
Copy link
Author

Yeah sorry, was late when I wrote that.

I'll add more detail shortly..

@simonmorley
Copy link
Author

Apologies, I have no idea what that template is :(

However, the test that fails outside of your gem (improvised), and within our application is as follows:

describe "When I update by Nas model", focus: true do

    it "should save a version when I update the correct attr" do
        PaperTrail.enabled = true
        nas = Nas.create slug: 123, description: 'Love Box', calledstationid: '11:22:33:44:55:66', channel: '01'
        expect(nas.slug).to be_present

        nas.update! description: 'Dont Love Box'
        expect(nas.versions.count).to eq 1

        version = nas.versions.last
        version.reify.save!
        expect(nas.reload.slug).to eq 123
    end

end

And the failure

Failure/Error: expect(nas.reload.slug).to eq 123

  expected: 123
  got: nil

  (compared using ==)

I can make this pass by using attr_accessor :slug but can't do so in production.

Friendly ID is set as so:

friendly_id :slug, use: :slugged

Any suggestions would be appreciated - I'll have a look through your tests later to see if there's anything outstanding.

@batter
Copy link
Collaborator

batter commented Oct 6, 2014

Not familiar with Friendly ID. You are talking about this gem?

@simonmorley
Copy link
Author

Yep. If you're not familiar, let me try and figure out what's going wrong..

Got a bit push to make this week and then will try and find time early next.

@batter
Copy link
Collaborator

batter commented Oct 16, 2014

@simonmorley - BTW, if this is an RSpec spec, you may need to set the :versioning => true context. Take a look at the docs on the README pertaining to the RSpec helper. If you can't get it to fail in production than this is likely your issue. PaperTrail 3.1.0 will change this behavior by making the RSpec helper an optional require that is not included by default (so PaperTrail will be turned on always by default unless the helper is included), as per discussion on #381.

@simonmorley
Copy link
Author

Yep we're using RSpec and papertrail's disabled in the test env. We just enable for these tests.

Will read through the links shortly.

If does fail in production too though - the slug isn't recorded.

@batter
Copy link
Collaborator

batter commented Oct 16, 2014

Oh ok, sorry, misread this and thought you had said everything was peachy in production and this was just an issue in your test suite.

@simonmorley
Copy link
Author

Ah no. Was failing in production first so we wrote a test to verify. Hadn't thought to test at all until it became a feature.

Haven't had a moment to look in more detail yet.

@hubb
Copy link

hubb commented Oct 20, 2014

hey @simonmorley, have you tried defining a custom should_generate_new_friendly_id? method in your model? (http://norman.github.io/friendly_id/file.Guide.html#Deciding_When_to_Generate_New_Slugs)

My setup seems similar to yours and it (..started to..) work fine after re-defining that method.

@simonmorley
Copy link
Author

That sort of works. Although, because we use SecureRandom.hex to generate the slug, we end up with a different value from the previous version.

It would seem something wipes the slug and, because it's changed, friendly_id overrides it with that method.

Is your slug the same before and after?

I get:

expected: "a9dec869-8690-4e91-a1dc-98ad9dfcfd13"
got: "b86475cf-e035-4ab6-ab9d-7a53e6730945"

Am going to have a look later but I think it's happening because the slug's generated after the version is recorded. And is therefore nil.

It sort of makes sense in my brain, just need to have a look at what's been saved and the order it's happening in.

@simonmorley
Copy link
Author

I have it working in my console. Not in my test.

Have changed to this:

  friendly_id :slug_candidates, use: :slugged

  def slug_candidates
    SecureRandom.uuid
  end

Removed any generators for the slug which were previous triggered before_create

But it's not making a lot of sense. As far as I can tell, we had it in this order:

  1. Friendly ID is triggered during a before_validation (https://github.com/norman/friendly_id/blob/5.0-stable/lib/friendly_id/slugged.rb#L236)
  2. We set the slug in a before create callback
  3. Papertrail records version after_update (here, I believe: https://github.com/airblade/paper_trail/blob/master/lib/paper_trail/has_paper_trail.rb#L77)

In the console, it looks ok:

https://gist.github.com/simonmorley/bd30ecbfb0b2cf044283

My test fails:

  1) Nas papertrail should store the old versions and save a version when updating the correct attributes.
     Failure/Error: expect(nas.reload.slug).to eq old

       expected: "3e5aec9b-dfaf-4346-9ff1-8d0074bf8fa8"
            got: "48cffd0e-4b47-4dc3-a4f1-8b210b5c6408"

       (compared using ==)
     # ./spec/models/nas_spec.rb:3151:in `block (3 levels) in <top (required)>'

Will continue to look.

@simonmorley
Copy link
Author

Actually, that's not working now. Don't understand why it's random.

@simonmorley
Copy link
Author

Sorry for the multiple posts this evening.

When rolling back to the last version, for some reason, it looks as though it's looking the model up with the wrong slug:

https://gist.github.com/simonmorley/272e5bb8e9095e13d119

Have looked for too long now.

@batter
Copy link
Collaborator

batter commented Oct 21, 2014

@simonmorley - What are you actually gaining by using FriendlyId? If you want a UUID, isn't it easier just to do something like this?

class Model < ActiveRecord::Base
  before_validation(on: :create) { self.uuid ||= SecureRandom.uuid }
end

# then on controllers you can do something like this:
class ModelController < ApplicationController
  helper_method :model

  def model
    @model ||= Model.find_by_uuuid(params[:id])
  end
end

@simonmorley
Copy link
Author

That's not a bad point. We've just used it from the start and haven't removed it.

It's only really this model though that we use it like the above.

It doesn't solve the actual problem in hand, whatever that is. It does actually solve my immediate problem of not being able to use your gem.

@simonmorley
Copy link
Author

Probably not the solution for most people using the two in combo but we ditched friendly id on one of the models we need to track.

However, the others cause us more issues. So, we either need to work round removing friendly id completely or try and understand better why papertrail isn't recording the slug.

@batter
Copy link
Collaborator

batter commented Oct 21, 2014

I hear you, and by all means you should use what you want to build your apps. I was just trying to figure out what the major advantages are to using the gem, and from reading their README, didn't see a ton of immediate value jumping of the wall for someone trying to do what you're doing, but I'm sure there must be more to the gem than what I'm seeing there on the surface.

I'm going to try to setup a test template and get to the bottom of this, I'll keep you posted if I have questions.

@batter
Copy link
Collaborator

batter commented Oct 21, 2014

Ok @simonmorley - I just setup a copy of the ActiveRecord template for gems in a Gist here. Running this on my local (after installing all the gems declared in the top of the file), this test passed. After reading the issue in more detail, I'm still not exactly sure what your issue is, so can you please try to recreate the problem by editing that template I've linked to? If I have a setup with real declarations and attributes, it will be much easier for me (or anyone else looking at this) to understand what's happening and what the problem is, and hopefully much easier for us to figure out what is wrong.

@simonmorley
Copy link
Author

To be clear, the problem is: when I revert to a previous version, the slug appears to be made null. As a result, friendlyid resets it.

Papertrail doesn't appear to store the slug. By the looks of it, it's the order the model is saved and validated.

Give me a week or so and I'll have a go with the template.

S

@alaibe
Copy link

alaibe commented Nov 10, 2014

Hey, I have the same issue on my project and after some research I think the problem might come from here: https://github.com/norman/friendly_id/blob/97ed06e4d4c4c9a57117c1e1c3c85eba94682844/lib/friendly_id/base.rb#L255-257

I think it is because of friendly id gem remove the slug from the dup and paper_trail use it.
I still don't know how to fix it, do you have a solution?

@batter
Copy link
Collaborator

batter commented Nov 10, 2014

@alaibe - This could be the issue here... When one of the version generating callbacks is triggered, we invoke this item_before_change method, where the first line invokes a dup of the current model. I'm guessing that is setting the slug to nil. Now that I think about it that method doesn't really need to do a full on dup, we could probably settle for just grabbing the before changes..

@batter batter closed this as completed in ca58ab6 Jan 29, 2015
@batter batter added this to the 4.0.0 milestone Jan 29, 2015
batter added a commit that referenced this issue Mar 2, 2015
…#404

Conflicts:
	lib/paper_trail/has_paper_trail.rb
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