Simple question.
I have a method in my ApplicationHelper that calls my SessionsHelper to load the current_user
i.e.
module ApplicationHelper
def some_helper_method
if current_user.respond_to? :some_method
#does stuff
end
end
end
module SessionsHelper
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find(...)
end
This works fine in my running application. However when running from Rspect the ApplicationHelper method cannot find current_user method. In the running app I know the method is available by some rails automagic class loading. But not sure what the best way is to make this work in Rspec.
There are multiple ways to handle this issue, but let me give you some background first.
You can configure rails to tell it what kind of helpers you are going to expose to your controllers and within your views with include_all_helpers.
In the old days you had a call to helper :all in your ApplicationController.
So that's how those methods get exposed.
Back to your question:
Solution numero uno: helper.stub(current_user: build(:user))
Solution numero due: helper.extend UserHandling
Prego
Related
I have a helper module ModelHelper. I want to use user_signed_in? method inside that helper module. But it shows error. How can I call this method inside helper file.
Method user_signed_in? defined in the Devise::Controllers::Helpers::ClassModule module. Long story short it just checks if scope authenticated in warden. So you can try to check it without Devise helpers
def #{mapping}_signed_in?
!!current_#{mapping}
end
def current_#{mapping}
#current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
end
I think that you can use current_user.present?
Anyway, rails helpers are very ugly and I advise to don't use it at all
I have been working with Ruby on Rails for a short time. Recently I implemented an authentication system for my application. I made a method available on 'application_helper.rb' to retrieve the current logged user (method called current_user).
The method just retrieves my User object if the session[:user_id] variable is present.
However I face the following problem.
If I place the current_user method in 'application_helper.rb', my controllers can't make use of it
If I place the current_user method in 'application_controller.rb', my views can't make use of it
What's the best approach to solve this problem? The easy way would be duplicate my code in both controller and helper, but I know there is a better and more correct way.
Thanks in advance
This is a common and well-solved problem.
Rails doesn't allow controllers to access helper methods. If you want to share a method between your views and controllers, you need to define the method in your controller, and then make it available to your views with helper_method:
class ApplicationController < ActionController::Bbase
# Let views access current_user
helper_method :current_user
def current_user
# ...
end
end
You can pass more than one method name to helper_method to make additional methods in your controller available to your views:
helper_method :current_user, :logged_in?
def current_user
# ...
end
def logged_in?
!current_user.nil?
end
Devise provide several helper methods such as current_user. It uses ActiveSupport's on_load to lazily load these helpers into the controllers.
However this means that when I first starts Rails, my attempt to alias these helper methods will not work correctly. For example:
# in my ApplicationController
alias_method :devise_current_user, :current_user
def current_user
user = devise_current_user
if !user && !devise_controller?
foo
end
return user
end
This would cause "method not found error" when Rails is first initialized. I can start Rails first, then add these code, then it would work (correctly aliasing and overriding the method).
How to properly do my aliasing/overriding for these on_load helpers?
I use MongoDB as a database in my Rails application with MongoID gem. I want to call the helper method from the model within after_create callback method. How is it possible?My model code is:
class Department
include ApplicationHelper
after_create :create_news
private
def create_news
#user = ApplicationHelper.get_current_users
end
end
And my helper code is:
module ApplicationHelper
def get_current_users
current_user
end
end
When I create new department then following error occur.
undefined method `get_current_users' for ApplicationHelper:Module
How to remove error? Thanks in advance.
I also use mongoid and use this all the time. Shouldn't be unique to mongoid though.
ApplicationController.helpers.my_helper_method
If you want a helper method that you can use in your views to return the current user, you can do so in your ApplicationController, something like this for example:
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
Then you can use this in any view.
If you want some arbitrary method in a model to know what user it's dealing with, pass #current_user in as an argument to the method when you call it in your controller.
Your code seems incomplete so I can't really see what you're trying to accomplish, but this is pretty standard practice.
Make sure the module file is named properly, meaning in your case application_helper.rb and it's located on the helpers library.
You can also try to include the helper in the ApplicationController (app/controller/application_controller.rb).
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.