I wanted a variable #user to be able to accessible across all the other controllers. How do i go with this.
Here is an example
Class User
def self.current=(u)
#current_user = u
end
def self.current
#current_user
end
end
You have to set User.current = somewhere, for example in your application controller.
Then in another model or controller just call User.current
You may want to have a current_user function into your ApplicationController, something like :
def current_user
#current_user ||= User.find( session[:user_id] ) if session[:user_id].present?
end
helper_method :current_user
You may now call current_user from all your controllers and views. #Intrepidd's method is cool too.
Variables are destroyed between each call to an action.
You must re-instantiate the #user each time.
To make it clean, you could do that in a before_filter
If you mean that you want the current user (for example), you could make a method/function in your model and call that.
Related
I have a method that checks for a boolean value on a table, and it returns false in my Users views (everywhere else it returns true). I am having trouble understanding why it is accessible, but returns false.
My code:
Application Controller:
protected
def current_user
#current_user ||= User.find_by_id(session_user_id) if session_user_id
end
helper_method :current_user
def current_customer
if current_user.customer and current_user.customer.master?
else
current_user.customer
end
end
helper_method :current_customer
Application helper method:
def customer_helper?
(current_user && current_user.customer.boolean_value?)
end
the customer_helper? method returns false in all of my Users views, even though my UsersController inherits from ApplicationController.
Any advice or help would be greatly appreciated.
current_user is nil within the helper method. I assume you are accessing this in a view where current_user has been exposed to the view from the controller. The attributes exposed to the view must be passed into the helper methods; they are are not automatically made available there.
If my assumptions are correct then your helper method should look something like this.
def customer_helper?(current_user)
(current_user && current_user.customer.boolean_value?)
end
You will then need to update the call to customer_helper? in your view to pass in the current_user.
I want to create my authentication system from scratch and I'm not really looking for debate in this area. My question is should I be using a helper file to provide methods such as current_user and signed_in? or is it preferred to provide these through the application_controller? or does it not matter in the slightest and I just need to get on with it?
I would put it in the ApplicationController, you can define something like
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
This will allow you to call #current_user from your views and controllers.
I am fairly new to Rails, so apologies if it's not an 'instance variable' I am talking about!
I am using Devise for authentication, so can use things like current_user throughout the app. The app I am building has a User model, but also a Keyholder model (who is a sort of moderator for that user), and a Guest (who has read-only access to some things for that user).
What I want to know is - can I set it up so that I can use e.g. access_user when logged in as the keyholder to access the same object as current_user - and if so, where do I put the code in my app? It's quickly becoming very verbose and un-Rails-like having to repeat myself otherwise.
What I am trying to achieve is being able to use 'access_user' instead of current_user, so that regardless of whether it is the user, keyholder or guest logged in, it will use the user object.
For example:
def access_user
if user_signed_in?
access_user = current_user
end
if keyholder_signed_in?
access_user = current_keyholder.user
end
if guest_signed_in?
access_user = current_guest.user
end
end
Thanks!
Class level instance variables could also help you.
def access_user
if user_signed_in?
#access_user = current_user
end
if keyholder_signed_in?
#access_user = current_keyholder.user
end
if guest_signed_in?
#access_user = current_guest.user
end
end
You can just set this method in ApplicationController, and expose it to a helper method.
class ApplicationController
helper_method :access_user
def access_user
#blah blah
end
end
When method in ApplicationController, it's available to all controllers.
When you use helper_method, it is exposed as helper method to be used in View. More about helper_method: http://apidock.com/rails/ActionController/Helpers/ClassMethods/helper_method
I'm trying to set the current user into a variable to display "Logged in as Joe" on every page. Not really sure where to begin...
Any quick tips? Specifically, what file should something like this go in...
My current user can be defined as (I think): User.find_by_id(session[:user_id])
TY :)
You might want to use something like Authlogic or Devise to handle this rather than rolling your own auth system, especially when you aren't very familiar with the design patterns common in Rails applications.
That said, if you want to do what you're asking in the question, you should probably define a method in your ApplicationController like so:
def current_user
#current_user ||= User.limit(1).where('id = ?', session[:user_id])
end
You inherit from your ApplicationController on all of your regular controllers, so they all have access to the current_user method. Also, you might want access to the method as a helper in your views. Rails takes care of you with that too (also in your ApplicationController):
helper_method :current_user
def current_user ...
Note: If you use the find_by_x methods they will raise an ActiveRecord::RecordNotFound error if nothing is returned. You probably don't want that, but you might want something to prevent non-users from accessing user only resources, and again, Rails has you covered:
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user
before_filter :require_user
private
def current_user
#current_user ||= User.limit(1).where('id = ?', session[:user_id])
end
def require_user
unless current_user
flash[:notice] = "You must be logged in to access this page"
redirect_to new_session_url
return false
end
end
end
Cheers!
It belongs in your controllers.
All your controllers inheirit from Application Controller for exactly this reason. Create a method in your Application Controller that returns whatever you need and then you can access it in any of your other controllers.
please help me to understand something. In Authlogic example in UsersController it's always used #current_user, so for instance:
def show
#user = #current_user
end
(taken from http://github.com/binarylogic/authlogic_example/blob/master/app/controllers/users_controller.rb)
Why is that? In my controllers I use just current_user instead of #current_user.
And besides - Authlogic works perfectly for me, but I don't see magic columns being populated (like last_login_at or last_login_ip). Should I initialize them somehow specifically besides just adding into migration?
UPD
After some investigation, I found that if there're only fields last_login_at and last_login_ip from "Magic fields", then they will not be populated. If I add a full set of magic fields, it is working perfectly.
UPD2
My concern regarding current_user is only about UsersController: why does it have #current_user and not current_user?
current_user is typically a method defined in app/controllers/application_controller.rb which sets the #current_user instance variable if it is not already defined -- here is an example:
def current_user_session
return #current_user_session if defined?(#current_user_session)
#current_user_session = UserSession.find
end
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.record
end
Re the "magic columns", these should be set by Authlogic automatically. For example, if your user sessions controller logs in a user:
#user_session = UserSession.new(params[:user_session])
#user_session.save
Authlogic should write the last_login_at and last_login_ip attributes for you. More info in the Authlogic docs under Module: Authlogic::Session::MagicColumns
As for last_login_at and last_login_ip, do you have current_login_at and current_login_ip fields in your table ? last_login_at and last_login_ip are set with the values of current_login_at and current_login_ip before they are reset.
I think the code from the example isn't a really good example.
You shouldn't use #current_user to set the #user variable. Because it won't work if the ApplicationController#current_user method isn't called before show action of the UserController. Basically they are both exactly the same after current_user is called once.
the User Controller should look like this
class UserController < ApplicationController
def show
#user = current_user
end
end
As for the Magic Columns I have no Idea why they don't work for you.