3

paper_trail is working great for us. But when we login to Heroku's console with heroku run console and then we make a change, the originator of the change is not set :(. So paper_trail has a mechanism for this:

In a console session you can manually set who is responsible like this:

>> PaperTrail.whodunnit = 'Andy Stewart'
>> widget.update_attributes :name => 'Wibble'
>> widget.versions.last.whodunnit              # Andy Stewart

You can avoid having to do this manually by setting your initializer to pick up the username of the current user from the OS, like this:
<bunch of code>

My question is how we can automate this with Heroku? Is there maybe something like this I can do?

heroku run console -e "PaperTrail.whodunnit = '123:console'"

Then each of us could simply create a console.sh file with the above using our individual user ids. Or is there another mechanism to automate this?

at.
  • 50,922
  • 104
  • 292
  • 461
  • 1
    You could test if the code is running in a console (http://stackoverflow.com/questions/13506690/how-to-determine-if-rails-is-running-from-cli-console-or-as-server) ; if yes then load a specific `.rb` file (in config/whodunnit.rb for example) which would ask the user's name before loading the rest (thanks to `STDIN` class) – MrYoshiji Apr 06 '15 at 20:03

2 Answers2

2

You can avoid having to do this manually by setting your initializer to pick up the username of the current user from the OS

That's basically the answer. Place the PaperTrail.whodunnit code in an initializer in config/initializers. These run when you start up the console. That would be the best place since it'll take effect when any of the devs login to the heroku console without having to change the command they run to do that:

# config/initializers/default_whodunnit.rb
if defined?(Rails::Console)
  PaperTrail.whodunnit = "whatever"
end

Update:

Heroku is a git server, just like Github, but you push to heroku to initiate a deploy. MrYoshiji's answer provides an option to give your devs a chance to state their usernames and have it set as the whodunnit. Just make his answer's code sample the contents of your default_whodunnit.rb initializer. This way you'll check in the whodunnit file, push to Heroku, and now any time a dev logs in to the heroku console they'll get asked for their username and that will set the whodunnit

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
DiegoSalazar
  • 13,361
  • 2
  • 38
  • 55
  • That's an hard-coded value which is the opposite of what the OP wants: he wants to be able to simply ask who is running the console to set the `whodunnit` of PaperTrail, not to always use the same identifier. – MrYoshiji Apr 06 '15 at 20:19
  • As you know, you can put _whatever_ there. Doesn't have to be a hardcoded value. – DiegoSalazar Apr 06 '15 at 22:48
  • This way sounds perfect! Each developer would simply have their own default_whodunnit.rb file that is not checked into github... – at. Apr 08 '15 at 01:20
  • No, that's not how it works. The `default_whodunnit.rb` file will _have to be checked in to git_ because it needs to be present in Heroku's repo for it to run when you `heroku run rails c`. Updated answer with more info. – DiegoSalazar Apr 08 '15 at 01:34
  • ahh, that's true @diego.greyrobot. hmm.. Can I pass anything to the console when I call `heroku run console`. If I could pass an environment variable or anything of that nature, I could read it in `default_whodunnit.rb` and developers would just have to use a very simple script to go to heroku's console that would pass their id. – at. Apr 08 '15 at 21:57
  • Honestly, probably the easiest way to make sure everyone always provides their username is to ask it every time they login. Just use `STDIN.gets` as described in the MrYoshiji's answer below. – DiegoSalazar Apr 09 '15 at 16:07
  • I've tested and initializers are ***not*** getting called when a console is started. Only when the server starts up. – at. Apr 16 '15 at 20:15
0

You could do this in your application.rb file:

if Rails.const_defined? 'Console'
  STDOUT.print "Enter your name for PaperTrail.whodunnit : "
  username = STDIN.gets.split("\n").first
  puts "Hello #{username}!"
  PaperTrail.whodunnit = username
end

Only when you will launch a console, the user will be asked to fill a username which will be used as the author of the changes.

MrYoshiji
  • 54,334
  • 13
  • 124
  • 117
  • This is great, I didn't know you could do this upon launching a console. Though @diego.greyrobot's way is even easier. – at. Apr 08 '15 at 01:21
  • Where do you put this exactly in the `application.rb` file? I can't get this to run when a console is launched. It seems nothing in `application.rb` is called when a console is launched. – at. Apr 16 '15 at 20:16
  • @at. If I use it at the very end of my `application.rb`, when I launch the server I am asked to enter a name ONLY when I open a console. Eventually provoke an error inside the `application.rb` file to make sure Ruby is reading it (divide an integer by zero, try to add an array to a hash, anything that would raise an error actually). – MrYoshiji Apr 16 '15 at 20:22