This method was adapted from this blog post.
So, you are creating a thing (record) or maybe you are updating it. You’ve added created_by and updated_by fields to your model, and you’ve made these integers with the intention of them both being foreign keys to the Users model.
Maybe you’ve even setup a belongs_to relationsion to your User model like so:
belongs_to :creator, :foreign_key => ‘created_by’, :class_name => ‘User’
belongs_to :updater, :foreign_key => ‘updated_by’, :class_name => ‘User’
end
(this way you can refer to thing.creator and thing.updater)
Now, you want to actually set these fields when you create a record or update a record. Problem is, your current_user method is a controller method, and isn’t available in your model layer.
Well, this IS a problem. There are many ways to hack it- but here’s the best approach. I’m going to do this backwards for clarity.
1. Make user_info.rb in your models directory
def current_user
Thread.current[:user]
end
def self.current_user=(user)
Thread.current[:user] = user
end
end
2. Now you need the TrackUsers class, which is real simple. Make another file in your models class called “track_users.rb”. Notice that we’re mixing in the UserInfo module we just created.
# mix me into the OBSERVER for any class you want to set the created_by, updated_by fields
include UserInfo
def before_update(record)
record.updated_by = current_user.id if current_user
end
def before_create(record)
record.created_by = current_user.id if current_user
end
end
3. Make an observer class for Thing (you can make this in your models folder). Call the file “thing_observer.rb”. Notice that all this basically does is mix in the TrackUsers module.
include TrackUsers
end
4. Setup an Observer for your (this goes inside the Rails::Initializer.run do |config| block)
:thing_observer
]
5. In your ApplicationController add this:
# … some more of your code …
protected
def set_user
if current_user
UserInfo.current_user = current_user
end
end