CanCan - checking permissions inside a model - ruby-on-rails

im starting here with cancan and i would like to know how can i check for permissions inside a model or the best way to achieve what i want that is:
In my User form i have checkboxes for roles assignment but only Admins can do that. i Already hide the checkboxes in the html with <% if can? :assign_roles, #user %> but a bad intentioned user may edit the html and add the checkboxes and choose wich role he wants.
So i decided to use a before_save method to check whether the current_user can assign roles but i dont have access to can? method inside models.
Is there a better way to make this verification?

You can try this to archive your goal. So you will be able to use can? and cannot? methods inside your models in your model context.

Related

I want to change the page view based on whether the user is an admin

In rails, I have a model for users which has a flag for admins (yes, no). If the logged_in user is an admin, I'd like to be able to show different elements of the page using erb.
I'm currently doing this with logg in users vs non logged in users using this code
<% if current_user %>
But how would I specify if current_user is admin in the erb?
Or, is erb the best place to do this since it is exposed to the browser? If not, any suggestions for other ways to accomplish this in the model or controller?
I'm not using Devise for the user authentication currently.
When you say they have a flag, does that mean they have an attribute called admin?
If so, any model with a boolean in rails, you can check with:
<% if current_user.admin? %>
If there is another way of determining whether the user is an admin or not, you'll need to add an admin? method to the user class, which you can use to determine their status in the view.
You can use user is_admin column name in views.
<% if current_user.is_admin? %>

users#edit needs to be different depending on who views it

I made a website where people can subscribe to a service.
Currently, users#edit is for the users themselves to edit information like passwords.
However, I want admins to be able to visit the edit page to be able to edit things like expiry_date. Obviously users themselves can't be allowed to edit their own expiry date for the subscription, so I want to limit this only to admins. I'm thinking something like using <%= if current_user.admin? %> and putting the expiry date form fields into there is good enough, but am I mistaken?
No, you're right. To make it simple, display the form field only if current_user is admin.
Create a method admin? in you application_helper.
def admin?
current_user.admin?
end
And then in your form partial, add
<% if admin? %>
<!-- display the field -->
<% end %>
However if you run into a situation where a lot of actions require only admins to view, I would suggest you to create a separate namespace for admins.
For more, see http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing

application with multiple "accounts", each containing multiple users

I am trying to build an application with multiple "accounts", each containing multiple users.
I've started with the gem Devise to create user authentication, and I've created Accounts and Preferences MVC's with scaffolding.
The Account model has_one Preferences, and has_many Users
The User model and Preferences model belongs_to my Account model
I've tested these relationships in the console and they seem to work..
What I would like to do, is make sure that when users are logged in, they can only view records associated with their account. From what I've seen, the current_user helper can be used, but I would like to use something like a "current_account".
1. First question is, is there a resource, Gem, method that can help me to create this current_account variable?
2. Second question would be, what do I need to put in my View for this to work? For instance, if a user wants to update his Preferences associated with his account, how would we call this in the _form partial, would if be something like this?
<%= #account.preference.opt_in %>
and if they wanted to see all of the users in the account, would it be something like this?
<% #customer.user.each do |account| %>
<%= user.email %>
<% end %>
Please let me know if I'm overlooking anything major, I've been working on this the last few days.
If I understand correctly, you are looking for a multi-tenancy solution. If so, you don't need to come up with your own solution, as there are well established patterns out there.
You can try the Milia gem, which fits in nicely with devise.

if can? in Ruby on Rails

In a Ruby on Rails application that I inherited from someone, I have code that looks like so
<% if can? :create, :objects %>
<%= link_to 'Add New Object', new_object_path %>
This web application has a login and users have different permissions that are defined in a table called groups_roles (which groups (ex. admin, user) have which roles (ex. add new objects))
I want to add new permissions, so where do I do that at? Where are these things defined? How does Ruby know which table to get the different permissions from, and how does it know what :create and :objects are in the code above?
The app seems to be using the cancan gem by ryan bates. You can specify the permissions in the app/models/ability.rb file.
It simply reads the ability file to determine if a user can perform some action or not. These actions correspond directly to the actions you have defined in the controller class.
Cancan has a great wiki at its github repositiory. Also, the screencast by ryan is an excellent place to start off with.
I do not know how the application is working, but the can? comes from the cancan gem. See the screencast.

Way to see which rails controller/model is serving the page?

This might be a slightly odd question, but I was wondering if anyone know a Rails shortcut/system variable or something which would allow me to keep track of which controller is serving a page and which model is called by that controller. Obviously I am building the app so I know, but I wanted to make a more general plugin that would able to get this data retroactively without manually going through it.
Is there any simple shortcut for this?
The controller and action are defined in params as params[:controller] and params[:action] but there is no placeholder for "the model" as a controller method may create many instances of models.
You may want to create some kind of helper method to assist if you want:
def request_controller
params[:controller]
end
def request_action
params[:action]
end
def request_model
#request_model
end
def request_model=(value)
#request_model = value
end
You would have to explicitly set the model when you load it when servicing a request:
#user = User.find(params[:id])
self.request_model = #user
There are a number of ways that I know of:
First you can do rake routes and check out the list of routes.
Second you could put <%= "#{controller_name}/#{action_name}" %> in your application.html.erb and look at the view to see what it says. if you put it at the extreme bottom you'll always get that information at the bottom of the page.
The controller can be accessed through the params hash: params[:controller]. There isn't really a way to get the model used by a controller though, because there is no necessary correlation between any controller and any model. If you have an instance of the model, you could check object.class to get the model's class name.

Resources