I've created a rails app using Active Admin on Nitrous.io and all is working in that dev environment. I am using Devise/CanCanCan for authentication/authorisation
When I push to heroku, and try and access Active Admin, I get the following error:
Started GET "/admin" for 91.226.23.198 at 2014-09-06 21:15:49 +0000
Processing by Admin::ProductsController#index as HTML
NoMethodError (undefined method `include?' for nil:NilClass):
app/models/user.rb:8:in `role?'
app/models/ability.rb:6:in `initialize'
My user model is like so:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
def role?(r)
role.include? r.to_s
end
end
Ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role? :administrator
can :manage, :all
elsif user.role? :moderator
can :manage, Product
can :manage, User, :id => user.id
cannot :destroy, User
#can :read, ActiveAdmin::Page, :name => "Dashboard"
can :read, ActiveAdmin::Page, :name => "Contact Us"
can :read, ActiveAdmin::Page, :name => "About x"
can :read, ActiveAdmin::Page, :name => "FAQ"
#can :manage, [Page, Unit, Category, News]
else
can :read, Product
can :manage, User, :id => user.id
cannot :destroy, User
#can :read, ActiveAdmin::Page, :name => "Dashboard"
can :read, ActiveAdmin::Page, :name => "Contact Us"
can :read, ActiveAdmin::Page, :name => "About x"
can :read, ActiveAdmin::Page, :name => "FAQ"
end
end
end
What am I doing wrong?
I've tried rebooting the heroku server multiple times.
Thanks for your help guys.
Cheers!
Ok finally got a solution to this one. The issue was the default user created by Active Admin didn't include a role, so I seeded a user with a role = 'administrator' and was able to login with this user and it all worked.
Thanks for all the help.
Related
My requirement is, i have to be able to register as a Super Admin/ admin / Guest and after that, i have to create a sample project as a Super Admin/ admin / Guest.
Super admin have all the permissions like Create,view, edit, delete. Admin have permissions like edit, view and Guest has to have only create access.
But, in my application, Guest is also getting all the permissions like create, update, delete on projects list.
To resolve this problem,
The gems which i used are:
gem 'devise'
gem 'cancancan', '~> 1.10'
gem 'rolify'
for redirection based on the role is in devise / registration / new.html.erb:
once, i create a new user,(by selecting radio buttons) i was able to save its value 1 (for super admin) / 2 (Admin) / 3(Guest) into the database
app/models/ability.rb:
class Ability
include cancan::Ability
def initialize(user)
user ||= User.new
if user.has_role?(:super_admin)
can :manage, :all
elsif user.has_role?(:admin)
can :create, Project
can :update, Project do |project|
project.ongoing?
end
can :read, Project
elsif user.role?(:guest)
can :create, Project
end
end
end
app/models/role.rb:
class Role < ActiveRecord::Base
resourcify
has_and_belongs_to_many :users, :join_table => :users_roles
belongs_to :resource,
:polymorphic => true,
validates :resource_type,
:inclusion => { :in => Rolify.resource_types },
:allow_nil => true
scopify
end
app/models/users.rb:
class User < ActiveRecord::Base
rolify :role_cname => 'Usertype'
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
has_many :projects, dependent: :destroy
def super_admin?
has_role?(:super_admin)
end
def admin?
has_role?(:admin)
end
def guest?
has_role?(:guest)
end
end
Well for starters in your last statement you are calling:
elsif user.role?(:guest)
whereas in the others you are calling
elsif user.has_role?
Any questions ask below. Since I am not able to comment yet.
I am using gem 'devise' and 'cancancan' for defining roles for user. problem is when I run rails server its says: undefined method 'admin?' for nil:NilClass
ability.rb:
class Ability
include CanCan::Ability
def initialize(user)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
end
User model:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :projects
def admin?
self.admin
end
end
What could be the problem?
I'm guessing the line from where the error is originating is something like:
if can? :manage, #object
# ...
This is likely causing an error because your user is not logged in.
The method defining the abilities looks like this:
def initialize(user)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
So, if you have no user, the line user.admin? will cause an error because user is nil and nil has no admin? method.
I would do something like this:
def initialize(user)
if user.try(:admin?)
can :manage, :all
else
can :read, :all
end
end
try in Ruby won't throw an error but will return nil if the method doesn't exist.
(I have not tested this and since you're not sharing the error, I'm taking some liberties in the response.)
I'd also like to point out that if the admin attribute on your User model is a boolean, you don't need to define this method—Rails does that automatically for you.
def admin?
self.admin
end
ability
class Ability
include CanCan::Ability
def initialize(user)
if user.has_role? :admin
can :manage, :all
else
can :read, :all
end
end
end
Hey there,
I am fairly new to Rails and I've managed to create a Favorite controller for my Items(Tools) and Users, which works totally fine.Now I am trying to do the same just in that user module. So users are able to favorite other users. I played around, and came up with this:
I am getting this error in the browser when accessing /users/index view:
NoMethodError in Users#index
undefined method `favorite_user_path' for #<#<Class:0x8ca77b8>:0x8ca50b8>
Here is my code:
app/models/favorite_user.rb
class FavoriteUser < ActiveRecord::Base
belongs_to :c_user_id
belongs_to :user_id
end
app/models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :tools
# Favorite tools of user
has_many :favorite_tools # just the 'relationships'
has_many :favorites, through: :favorite_tools, source: :tool # the actual tools the user favorites
# Favorite users of user
has_many :favorite_users # just the 'relationships'
has_many :userfavorites, through: :favorite_users, source: :user # the actual users the user favorites
has_many :userfavorited_by, through: :favourite_users, source: :user # the actual users favoriting a user
mount_uploader :avatar_filename, AvatarUploader
end
app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :find_user, only: [:show, :favorite]
# Add and remove favorite recipes
# for current_user
def userfavorite
type = params[:type]
if type == "favorite"
current_user.userfavorites << #user
elsif type == "unfavorite"
current_user.userfavorites.delete(#user)
else
# Type missing, nothing happens
redirect_to :back, notice: 'Nothing happened.'
end
end
def index
#users = User.all
end
def show
#tools = Tool.where(user_id: #user).order("created_at DESC")
#tool = Tool.find(1)
end
private
def find_user
#user = User.find(params[:id])
end
end
app/views/users/index.html.haml
- #users.each do |user|
= image_tag gravatar_for user if user.use_gravatar == true
= image_tag user.avatar_filename.url if user.use_gravatar == false
%h2= link_to user.username, user
%p= link_to "Favorite", favorite_user_path(user, type: "favorite"), method: :get
%p= link_to "Unfavorite", favorite_user_path(user, type: "unfavorite"), method: :get
app/config/routes.rb
resources :users, only: [:index, :show, :userfavorite] do
get :userfavorite, on: :member
end
I hope the provided data is enough, if not please tell me. I'm grateful for all Your replies.
You haven't declared any such path in the routes file. As per your routes file you can use named path like
userfavorite_user_path(user_id)
I have been trying to get rolify gem to work FOREVER. I have cancancan and devise as well, i basically have a signup page with email, password, password_confirmation, and a dropdown box selecting role. and when i click sign up it gives me an error to the segment of code creating the DDbox. Can anyone help me get this working ? my ability.rb is this
`class Ability
include CanCan::Ability
def initialize(user)
user ||=User.new
if user.has_role? :admin
can :manage, :all
elsif user.has_role? :regularUser
can :read, Menu
elsif user.has_role? :institution
can :read, Menu
elsif user.has_role? :franchiseOwner
can :read, Menu
end
# Define abilities for the passed in user here. For example:
#
# user ||= User.new # guest user (not logged in)
# if user.admin?
# can :manage, :all
# else
# can :read, :all
# end
#
# The first argument to `can` is the action you are giving the user
# permission to do.
# If you pass :manage it will apply to every action. Other common actions
# here are :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on.
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
# class of the resource.
#
# The third argument is an optional hash of conditions to further filter the
# objects.
# For example, here the user can only update published articles.
#
# can :update, Article, :published => true
#
# See the wiki for details:
# https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
end
end `
and this the the dropdown box code snippet from my view/devise/registation/new.html.erb..
<%= user_form.select :role, options_from_collection_for_select(Role.all,"Institution","Regular User", "Franchise Owner")%>
this is my User.rb model
`class User < ActiveRecord::Base
rolify :before_add => :before_add_method
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
def before_add_method(role)
end
end`
and my users_controller
`class UserController < ApplicationController
def index
#users = User.all
end
def new
#user = User.new
end
# POST /userss
# POST /users.json
def create
#user = User.new(user_params)
#user.add_role params[:user][:role]
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :role)
end
end`
User.new does not save a record and as such will not have an id.
Try saving the user either with user.save or by using User.create instead so it has an id before adding the role. Otherwise the role wont have a user_id to use for it's association.
user = User.create(:email => 'foo#bar.com', :password => 'somestring', :password_confirmation => 'somestring')
user.add_role :rolename
I am trying to create permissions in my Rails app with Devise and Cancan.
ability.rb:
class Ability
include CanCan::Ability
def initialize(user)
if user.role == 'admin'
can :manage, :all
else
can :read, :all
end
end
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :role
# attr_accessible :title, :body
def role(role)
roles.include? role.to_s
end
end
view
<% if can? :update, review %>
<p><p><i><a href = '/products/<%= #product.id %>/reviews/<%= review.id %>/edit'>Edit</a>
<% end %>
I get an error saying undefined method `role' for nil:NilClass for this line in the view. Any advice on how to fix this?
I've been trying to use https://github.com/ryanb/cancan/wiki/Role-Based-Authorization as a guide
try adding
user ||= User.new # guest user (not logged in)
to see if that fixes your role error.
class Ability
include CanCan::Ability
user ||= User.new # guest user (not logged in)
def initialize(user)
if user.role == 'admin'
can :manage, :all
else
can :read, :all
end
end
end
that way you can rule out user being nil.
Check out this screencast by the creator of the cancan gem. It explains what you are trying to do in depth a little better than the link you are following.