I have 3 tables
items (columns are: name , type)
history(columns are: date, username, item_id)
user(username, password)
When a user say "ABC" logs in and creates a new item, a history record gets created with the following after_create filter. How to assign this username ‘ABC’ to the username field in history table through this filter.
class Item < ActiveRecord::Base
has_many :histories
after_create :update_history
def update_history
histories.create(:date=>Time.now, username=> ?)
end
end
My login method in session_controller
def login
if request.post?
user=User.authenticate(params[:username])
if user
session[:user_id] =user.id
redirect_to( :action=>'home')
flash[:message] = "Successfully logged in "
else
flash[:notice] = "Incorrect user/password combination"
redirect_to(:action=>"login")
end
end
end
I am not using any authentication plugin. I would appreciate if someone could tell me how to achieve this without using plugin(like userstamp etc.) if possible.
You could write an around_filter in ApplicationController
This can be done easily in few steps by implementing Thread.
Step 1:
Step 2:
Now you can easily get current user as
User.current
The
Thread
trick isn't threadsafe, ironically.My solution was to walk the stack backwards looking for a frame that responds to
current_user
. If none is found it returns nil. Example:It could be made more robust by confirming the expected return type, and possibly by confirming owner of the frame is a type of controller...
Rails 5
Declare a module
Assign the current user
Now you can refer to the current user as
Current.user
Documentation about thread_mattr_accessor
Rails 3,4
It is not a common practice to access the
current_user
within a model. That being said, here is a solution:Set the
current_user
attribute in aaround_filter
ofApplicationController
.Set the
current_user
after successful authentication:Finally, refer to the
current_user
inupdate_history
ofItem
.The Controller should tell the model instance
Working with the database is the model's job. Handling web requests, including knowing the user for the current request, is the controller's job.
Therefore, if a model instance needs to know the current user, a controller should tell it.
This assumes that
Item
has anattr_accessor
forcurrent_user
.The Rails 5.2 approach for having global access to the user and other attributes is CurrentAttributes.