I'm Trying to achieve that the user can see only HIS applications, and not the "Application Index" containing all the applications from all Users.
My Header:
<%= link_to "My Application ", current_user.application %>
My Abilities:
if user.has_role? :speaker
can :read, Application do |application| # heres the problem
application.try(:user) == user
end
can :create, Application
can :update, Application do |application|
application.try(:user) == user
end
end
Currently the User can access the Application/Index page. But the restriction should give him only access to:
http://localhost:3000/applications/8 # 8 being his application
What am i missing ?
Might be not the cleanest way, but this works:
in index action:
if current_user.has_role? :admin
#applications = Application.all
else
#applications = current_user.application
end
in index.html.erb
<% if current_user.has_role? :admin %>
<%= render #applications %>
<% else %>
<% #applications.title %> etc..
<% end %>
Note: current_user.application is because user model has_one :application
Related
I am trying display the task related to logged in user but on my html page nothing show except the tag data
task_controller.rb
class TaskController < ApplicationController
def all_task
if current_user.present?
#all_task = Task.find_by_user_id(#current_user.id)
render template: 'task/allTask'
end
end
end
routes.rb
get 'all_task' => 'task#all_task'
task.erb
<p>All Task</p>
<% if user_signed_in? %>
<%#all_task.daily_task %>
<%#all_task.date %>
<%#all_task.created_at %>
<%end %>
Start by setting up an assocation between users and tasks:
class User < ApplicationRecord
# ...
has_many :tasks
end
Then setup the route and controller:
get '/user/tasks', to: 'users/tasks#index', as: :user_tasks
# app/controllers/users/tasks_controller.rb
module Users
class TasksController < ApplicationRecord
before_action :authenticate_user!
# display all the tasks belonging to the currently signed in user
# GET /user/tasks
def index
#tasks = current_user.tasks
end
private
# You don't need this if your using Devise
def authenticate_user!
unless current_user
redirect_to '/path/to/your/login',
notice: 'Please sign in before continuing'
end
end
end
end
Note that when you have a route like this that displays resources that belong to the current user you should use a callback to bail early and redirect the user to sign in instead of using if current_user.present? and giving a response which is meaningless to the user. This code should be DRY:ed into your ApplicationController (even better yet is to not reinvent the auth wheel).
You can link to the users tasks with:
<% if current_user.present? %>
<%= link_to 'My tasks', user_tasks_path %>
<% end %>
In your view you need to iterate across the returned tasks:
# app/views/users/tasks/index.html.erb
<p>All Tasks</p>
<% if #tasks.any? %>
<% #tasks.each do |task| %>
<%= task.daily_task %>
<%= task.date %>
<%= task.created_at %>
<% end %>
<% else %>
<p>You don't have any tasks.</p>
<% end %>
You can cut duplication here by using partials.
Can you make sure if the instance variable #current_user is defined? If not, try the following:
class TaskController < ApplicationController
def all_task
if current_user.present?
#all_task = Task.find_by_user_id(current_user.id)
render template: 'task/allTask'
end
end
end
instead of
class TaskController < ApplicationController
def all_task
if current_user.present?
#all_task = Task.find_by_user_id(#current_user.id)
render template: 'task/allTask'
end
end
end
I have a User model class I have created with Devise.
I have a role field (admin=0, user=1) in my model.
Screenshot of my database:
HTML View
<% if current_user.active_admin? %>
<%= render 'layouts/admin' %>
<% else %>
<%= render 'layouts/user' %>
<% end %>
Model
def active_admin?
#your logic here
end
I want to login. If I am an admin check role is 0 render to layouts/admin else I am a user check role is 1 render to layouts/user.
How do I write code in the model to do this?
In your user.rb file:
class User < ActiveRecord::Base
def active_admin?
role == 0
end
end
In your view:
<% if current_user.active_admin? %>
<%= render 'layouts/admin' %>
<% else %>
<%= render 'layouts/user' %>
<% end %>
As Mark says, you can just check role for 0 or 1.
Any column in your database will map directly to a method on the model.
A couple of points:
If you're using Rails 5 you'll need to inherit from ApplicationRecord rather than ActiveRecord::Base.
In newer versions of Ruby you can use the #zero? method:
class User < ApplicationRecord
def active_admin?
role.zero?
end
end
No need of adding a method for checking the roles, you can directly achieve this by below change. It will return true for anything other than 0.
<% if current_user.role? %>
<%= render 'layouts/user' %>
<% else %>
<%= render 'layouts/admin' %>
<% end %>
One way can be add an method on application controller as
def after_sign_in_path_for(resource_or_scope)
if current_user.role==0
#your admin path
else
root_path
end
end
def authenticate_admin
unless (user_signed_in? and current_user.role !=0 )
redirect_to '/users/sign_in'
end
end
add to the required controller
before_filter :authenticate_admin
layout 'admin'
I'm managing user and admin roles with cancan. I want the user to have access to certain views ("Cursos", "Credenciales", ) but cancan does not allow it. How can I give them access? So, what is happening is that it tries to access the route but goes back to the root as I specified it to do it in the application controller. (Of course it is supposed to access to the controller through that route.) Thanks for your help!!
index.html.erb
<% if current_user %>
<% if can? :new, #user %>
<% if can? :new, #empleado %>
<li><%= link_to "Lista de Empleados", empleados_path %></li>
<li> <%= link_to "Agregar Empleado", new_empleado_path %></li>
<% end %>
<% end %>
<li><%= link_to "Cursos", cursovence_path %></li>
<li><%= link_to "Credenciales", credencialvence_path %></li>
<% end %>
ability.rb
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.admin?
can :manage, :all
else
can :read, :all
can :display, :all
end
end
routes.rb
devise_for :users
root 'empleados#index'
resources :empleados
resources :users
post '/empleados/:id' => 'empleados#display'
get '/cursovence' => 'empleados#indexCursoVence'
get '/credencialvence' => 'empleados#indexCredencialVence'
get '/proxvacas' => 'empleados#indexProxVacas'
empleados_controller.rb
class EmpleadosController < ApplicationController
before_action :authenticate_user!
# load_and_authorize_resource - It did not work with this validation
load_resource #So, I changed it for only this one
def index
....
end
def new
....
end
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
rescue_from CanCan::AccessDenied do |exception|
flash[:error] = "Access denied."
redirect_to root_url
end
end
In cancan you can assign abilities based on symbols not classes (in case you don't have models to base your abilities on) https://github.com/ryanb/cancan/wiki/Non-RESTful-Controllers
So in your view check for can? :index, :cursos and can? :index, :credenciales given that you added can :read, :all in your ability
<% if can? :index, :cursos %>
<li><%= link_to "Cursos", cursovence_path %></li>
<% end %>
<% if can? :index, :credenciales %>
<li><%= link_to "Credenciales", credencialvence_path %></li>
<% end %>
I'm currently trying to set up an admin page. I'm creating a form in the page where I can update user's profile using checkboxes, but when I tried to submit, I get sent to a routing error page with uninitialized constant AdminController
my routes.rb
namespace :admin do
get '', to: 'dashboard#index', as: '/'
end
resources :admin do
collection do
post :edit_multiple
put :update_multiple
end
end
controllers/admin/dashboard_controller.rb
class Admin::DashboardController < ApplicationController
def index
#users = User.all
#admin = User.new
end
def edit_multiple
end
def update_multiple
end
end
views/admin/dashboard/index.html.erb
<%= form_tag edit_multiple_admin_index_path do |f| %>
<table>
<% #users.each do |user| %>
<% if !user.public %>
<tr>
<td><%= check_box_tag "user_ids[]", user.id %></td>
</tr>
<% end %>
<% end %>
</table>
<%= submit_tag "Edit Checked" %>
<% end %>
Anyone know when I'm getting this error?
Thanks!
Change your routes.rb file to:
namespace :admin do
get '', to: 'dashboard#index', as: '/'
resource :dashboard do
post :edit_multiple
put :update_multiple
end
end
I have added a before filter and def check priv to the users controller. It is suppose to be setup so that only admin can view/edit all profiles, and that only the created User can view their own profile. As before anyone could view/edit profiles. I have tried a few methods, none work. When I go to view profile as admin or even regular user I get the "not authorized" message.
Any help would be appreciated.
users_controller:
before_filter :check_privileges, :only => [:edit, :update]
def check_privileges
unless current_user.admin? || current_user.id == params[:id]
flash[:warning] = 'not authorized!'
redirect_to root_path
end
end
index.html:
<%= link_to user.name, user %>
<% if (current_user.admin? || current_user) == #user %>
<%= link_to "Edit #{user} profile", user %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?"} %>
<% end %>
I have a similar method in my app, try something like this:
def check_privileges
return if current_user.admin? # this user is an admin, if is not the case do:
flash[:warning] = 'not authorized!'
redirect_to root_path
end
UPDATE 1
Again, try to change the if condition as the follow
if (condition || condition)
or
if ((condition) || (condition))
The problem is that Ruby parsers stop at the first condition if not explicited declared.
UPDATE 2
I think that there are an error in the parentheses on your index.html.erb, try the following:
<%= link_to user.name, user %>
<% if (current_user.admin? || (current_user == #user)) %>
<%= link_to "Edit #{user} profile", user %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?"} %>
<% end %>
Food for thought maybe you could do something like this:
def correct_user
#user = User.find(params[:id])
if current_user.role? :administrator
#Allow admin to access everyone account
else
access_denied unless current_user?(#user)
end
end
Then inside your view your view do the if statement. Or alternatively my best suggestion is to go with something like CanCan. Something like this will allow you to set up role authentication really easily. If you have a look at it you can set a certain amount of rule in your ability.rb which you can then enforce on the view.
If you WERE to go with the method of CanCan you could do something like this in your ability.rb
def initialize(user)
user ||= User.new # guest user
# raise user.role?(:administrator).inspect
if user.role? :administrator
can :manage, :all
can :manage, User
elsif user.role? :employee
can :read, :all
end
The above is an example.... So that in your views you can enforce this type of rule by doing something like
<%= link_to user.name, user %>
<% if can? :manage, #user %>
<%= link_to "Edit #{user} profile", user %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?"} %>
<% end %>
Something like this should work. Your options are there hope this helps :)