CanCan - "user" parameter is nil - Rails 4 - ruby-on-rails

I am using Rails 4.0.1 and ruby 2.1.1. I am trying to integrate cancan with rails_admin. My application_controller.rb looks like this
helper_method :current_user
private
def current_user
#current_user ||= User.find_by(email: session[:user_id]) if session[:user_id]
end
My current_user helper method is working fine from rest of the application. My ability.rb looks like this
class Ablity
include CanCan::Ability
def initialize(user)
if user
can :access, :rails_admin
end
end
end
Control is not going inside the if condition at all, which means the "user" parameter is "nil". When I try to access rails_admin I get a CanCan::AccessDenied exception. Where am I going wrong?
Edit : I am not using devise for authentication
Update : I've replaced cancan with cancancan version 1.8. Still not working

Solved. In config/initializers/rails_admin.rb we have to specify the current_user_method as
config.current_user_method { current_user } # refers to the current_user helper method in my case
Now everything is working perfectly. I am surprised why this isn't specified anywhere in the documentation.

Related

How do you get Sorcery working with Grape in Rails?

How can you use a cookies based Sorcery authenticated session in Grape under Rails?
I am interested in utilizing commands like session and current_user from a grape controller.
Add the following helpers to your root API mount point:
class API < Grape::API
..
helpers APIHelpers
..
end
# add this to app/api/api_helpers.rb
module APIHelpers
include Sorcery::Controller
def session
env['rack.session']
end
def reset_session
if env['rack.session']&.respond_to?(:destroy)
session.destroy
else
env['rack.session'] = {}
end
end
def form_authenticity_token
session[:_csrf_token] ||= SecureRandom.base64(32)
end
def current_user
#current_user = login_from_session || nil unless defined?(#current_user)
#current_user
end
end
Including Sorcery::Controller gave me all the sorcery methods (login, current_user, etc), but there were a few missing session methods that needed to be added via the helpers to make sure sorcery was happy. Note, Grape does not provide the same CookieJar as rails, so you won't be able to utilize cookies.signed. This was not an issue for me, but it may be for you. I worked around the sorcery functions that would call a signed cookie.

want to customise the current_user methode of devise gem

I want to user current_user method for two purpose.
I have user gmail log in and personal registration from site.
But current_user method of devise gem is not working for gmail user.
for gmail user I used below method
helper_method :current_user
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
kindly help me to fix this.
Thanks
I got solution by my self letter on.
Below code is the solution of above problem
alias_method :devise_current_user, :current_user
def current_user
if session[:user_id].blank?
devise_current_user
else
User.find(session[:user_id])
end
end
This works fine for me

undefined local variable or method `current_user' cancancan

I'm working on a login/logout system. Instead of using devise, I created an active records User model and use sessions to remember if a user is logged in. Everything was working fine until I added these lines in the application_controller.rb to have a layout before login and one after.
layout :set_layout
def set_layout
if session[:current_user_id]
'afterlogin'
else
'application'
end
end
Now, after I log in and cancancan is being used somewhere in a html page I get undefined local variable or method 'current_user'. I think that I have to add a current_user method but I'm not exactly where and how to define it.
Edit: I already had something similar in another class that is being used by login:
class Admin::ApplicationController < ApplicationController
before_action :authorize
def authorize
begin
#current_user ||= User.find(session[:current_user_id]) if session[:current_user_id]
rescue ActiveRecord::RecordNotFound
session.destroy
redirect_to '/login',alert: 'Please login'
end
end
end
Should I modify this after I add that method ?
CanCanCan expects a current_user method to exist in the controller.
First, set up some authentication (such as Authlogic or Devise).
See Changing Defaults if you need different behavior.
I would suggest you to install Devise so that it comes with a complimentary current_user method.
FYI: https://github.com/plataformatec/devise
UPDATE
when a user logins successfully, you can store the user's id in session.
session[:current_user_id]=user.id
so that, in your applicationcontroller, you can do
def current_user
#current_user ||= session[:current_user_id] && User.find_by_id(session[:current_user_id])
end
helper_method :current_user

How get Devise's current_user method in Rails Engine

I have a Rails application that's using the Devise gem, and I'm creating a Rails Engine to mount in this app.
mount Comments::Engine => '/talk', :as => 'comments'
Within the Engine, I want to get the current_user instance from main application.
In {main_app}/initializers/comments.rb
Comments.user_class = "User"
Comments.current_user = "current_user" #current_user is Devise method(works fine in app)
In {engine}/lib/comments.rb
require "comments/engine"
module Comments
mattr_accessor :user_class, :current_user
def self.user_class
##user_class.constantize
end
def self.current_user
send(##current_user)
end
end
When I call Comments.current_user, I get the error "wrong constant name current_user".
What am I doing wrong?
Seams I'm solved problem.
I'd call current_user within Comments model and it didn't work.
However getting current_user from controller, works fine.
But this is not elegant way (.

How to make current_user always be not nil in Rails application?

Please, give me any idea about a little problem: in my Rails 3 app I need current_user always be NOT nil. I'm using Devise and CanCan for auth system and I thinking about how to implement "guest" user. For roles like "admin" it works fine ( if current_user.is? :admin), but if user is not logged in I wish to check not user_signed_in?, but the same way (if current_user.is? :guest) for example.
I think I need to put somthing creating current_user object ib before_filters of Application_Controller, but I dont' know how to create this global thing right way.
Thanks for any answers!
You could try it like this:
if current_user.try(:is?, :admin)
So it won't matter if current_user is nil
If you are using 'CanCan' you should be adding functionality like you mentioned into you Abilities class. For example:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
can :manage, :all if user.is? :admin
can :read, :all if user.is? :guest
end
end
For more information take a look through the Wiki or watch the screen cast:
https://github.com/ryanb/cancan/wiki
http://railscasts.com/episodes/192-authorization-with-cancan

Resources