Using whodunnit to get User Instance
Asked Answered
R

5

5

On my home page i display the latest updates using papertrail.

Controller

@contributions = PaperTrail::Version.all.order("created_at DESC")

View

<% @contributions.each do |v| %>
    <h2><%= v.item.name %><small>by </small></h2>
    <% v.changeset.each do |data| %>
      <h4><%= data %></h4>
    <% end %>
    <%= v.whodunnit %>
<% end %>

Here i get the associated user but only the ID with whodunnit, but i would like to get a user instance to get a username. So insted of v.whodunnit i would like v.user.username.

I have been looking at a similar question but cant seem to figure out a way create the relation between a version and a user.

User model

class User < ActiveRecord::Base
  has_many :versions, :foreign_key => 'whodunnit', :class_name => "PaperTrail::Version"
end

Version model

class Version < PaperTrail::Version
  belongs_to :user, :foreign_key => 'whodunnit'
end

EDIT

I get this when I have <%= v.user %> in view

undefined method `user' for #<PaperTrail::Version:0x007fb24c08e868>
Rheum answered 18/2, 2014 at 21:16 Comment(2)
What are the problems with your current version?Kremenchug
I get undefined method 'user' when trying to get v.user in my viewRheum
K
4

There is an alternative way to do it:

class Version < PaperTrail::Version
    ...

    def user
         User.find(whodunnit) if whodunnit
    end  
end

If you need to add user model to the PaperTrail::Version class itself, then add a new initializer to your app:

config/initializers/papertrail_monkey_patch.rb

module PaperTrail
    class Version
        def user
            User.find(whodunnit) if whodunnit
        end
    end
end
Kremenchug answered 18/2, 2014 at 21:58 Comment(3)
When i try to run <%= v.user %> with your method i get the same error as i did above. undefined method `user' for #<PaperTrail::Version:0x007fb24c1d7eb8>Rheum
I guess, I understood the problem. You v variable is of class PaperTrail::Version and not your custom Version. You need to monkey patch PaperTrail::Version class.Kremenchug
Ok thanks, any idea of how i can do this? Mind updating your answer?Rheum
C
5

An updated version of this for Rails 5.X

# config/initializers/paper_trail.rb
PaperTrail::Rails::Engine.eager_load!

module PaperTrail
  class Version < ::ActiveRecord::Base
    belongs_to :user, foreign_key: :whodunnit
  end
end
Cartulary answered 17/4, 2019 at 17:34 Comment(0)
K
4

There is an alternative way to do it:

class Version < PaperTrail::Version
    ...

    def user
         User.find(whodunnit) if whodunnit
    end  
end

If you need to add user model to the PaperTrail::Version class itself, then add a new initializer to your app:

config/initializers/papertrail_monkey_patch.rb

module PaperTrail
    class Version
        def user
            User.find(whodunnit) if whodunnit
        end
    end
end
Kremenchug answered 18/2, 2014 at 21:58 Comment(3)
When i try to run <%= v.user %> with your method i get the same error as i did above. undefined method `user' for #<PaperTrail::Version:0x007fb24c1d7eb8>Rheum
I guess, I understood the problem. You v variable is of class PaperTrail::Version and not your custom Version. You need to monkey patch PaperTrail::Version class.Kremenchug
Ok thanks, any idea of how i can do this? Mind updating your answer?Rheum
A
2

You can add the relationship to the version model

config/initializers/paper_trail.rb

    # paper trail config ...
    # ...

    module PaperTrail
      class Version < ::ActiveRecord::Base
        belongs_to :user, foreign_key: :whodunnit
      end
    end
Aa answered 5/8, 2017 at 19:18 Comment(0)
K
0

add a model

class PaperTrailVersion < PaperTrail::Version
    belongs_to :user, foreign_key: :whodunnit
end
Karney answered 27/9, 2021 at 14:8 Comment(0)
S
0

See the documentation on adding your own custom version model:

class UserVersion < PaperTrail::Version
  belongs_to :user, foreign_key: :whodunnit
end

And then specify the custom model in the class you're tracking changes on:

class Contribution
  has_paper_trail versions: {class_name: 'UserVersion'}
end

Doing this will allow you to also eager load the associated users if you need to display many versions at once:

Contribution.versions.includes(:user)
Streetlight answered 27/11, 2021 at 3:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.