I am using cancan and trying to get it to limit equipment shown for a specific company.
I have a company with many users that should only see equipment that belong to that company.
I thought cancan could do this based on this:
Rails 3 company account with many users, restrict access to data
So I tried this code:
can :manage, Equipment do |equipment|
user.company == equipment.company
end
In the equipment controller I have #equipment = Equipment.all which I figured would just pull the equipment for that users company, but of course it pulls them all. Is there an easy way to do this or do I need to do #equipment = Equipment.find_by_company_id(current_user.company) anytime I want to pull just that companies equipment. To make this worse I want to eventually break it down by groups and departments, but would rather not have to force myself into more big find queries. I am open to anything, plugins, suggestions, whatever will be the fastest way to fix this.
I could have added more code to this question, but I don't know that adding it all would really help the question.
Thank you very much
Toby
Try Equipment.accessible_by()
https://github.com/ryanb/cancan/blob/master/lib/cancan/model_additions.rb
Related
I find that the nickname and reference_id fields work differently across platforms and I'd like to get clarification on how they should be used.
With the API, I can retrieve and set both these fields.
In the web-based dashboard, both fields are displayed and can be edited if present, but there's no way to enter a nickname when creating a new customer.
In the Register iOS app, none of these fields are shown or editable. They're also absent when creating a new customer.
What I want to do is map Square Customers to our existing members, but we're facing three problems:
reference_id seems to map perfectly with our existing member numbers but, as mentioned, it's nowhere to be seen in the Register app.
Searching customers in the Register app only searches in names and emails. It would really help us if it searched in reference_id as well.
CustomerGroupInfo is read-only via the API (and not even an endpoint). We would map these to our membership levels.
As of now, I'm looking at ugly workarounds, but I wanted to know if something in the roadmap could help us out. Thanks in advance to the people at Square!
This might be an obvious issue for some one good with CanCanCan, but I am finding it hard to wrap my head around it.
I got an application that has many roles around it (campus_rep, campus_manager, operations_manager, admin etc). They all have acces to an 'admin' section but will see different menu options based on their role.
For example:
Admin can manage all 'Customers'
Operations managers can manage customers for the schools they belong to
Extract of ability.rb
if user.role == 'admin'
can :manage, JobApplication
elsif user.role == 'operations_manager'
can :manage, JobApplication, school_id: user.schools.map(&:id)
elsif ser.role == 'campus_rep'
# blah but nothing to do with JobApplication
end
I have been thinking to use if can? :manage, Customer but then even 'operations_managers' don't pass it which makes sense.
What is the recommended way to get out of a similar situation?
I tried if can? :manage, Customer.new(school: current_user.schools.first) which kinda works but looks not alright.
I though of doing some thing like adding can :see, JobApplication to both 'admin' and 'operations_managers' and then doing the check like if can? :see, JobApplication.
What is recommended? Is there any better way? Hopefully there is...
Also highly appreciate any advice in the matter
Your code mentions JobApplications but your question is mostly about Customers : I'll talk about Customers but the principle is the same for any model.
If I understand you correctly, you aim to pass a collection of customers to your view. But you only want the view to show those customers that your user (say an operations manager) is allowed to manage.
In that case your controller or view template code can filter the customers according to ability. So you would do something like
#customers = Customer.find_each.select { |cstmr| current_user.can? :manage, cstmr }
This will be quite slow if there are a lot of customers, so some programmers will try to bypass cancancan and design a database query instead. For example, you could query the database for all customers belonging to a particular school.
Your main misunderstanding is that you are trying to test abilities based on classes. However, your rules are based on individual objects. This is normal, so the normal way is to test each instance.
Reference: http://www.rubydoc.info/gems/cancancan/1.13.1#2__Check_Abilities___Authorization
This is a Rails app for a school. I'm using Devise for user accounts. So far each user has a .role of admin, teacher or student which restricts what the user can access and contribute in the app. I'm using user.email to log in. All is working great so far.
Now I've realized that I have a problem with sibling accounts. The unique user.email used for logging in is actually the parent's email address (since the students are minors) and now I have to account for a parent with two or more children who are students. I obviously can't have a student account for each child and use the same email address because it has to be unique (and I do want to keep the requirement in the validation).
Given that I already have a large chuck of the app done, what would be a nice DRY way to account for this situation?
I've searched this site and others but not really found anything that accounts for this situation.
One way I thought would be to change the role in the User model to parent and then have a separate Student model . A user with the role of parent could then has_many :students but this doesn't sit well with me.
Any general ideas/concepts would be appreciated, as would any pointers to articles or gems that would help me with this.
I don't know if it's the best way, but one approach would be to append a sibling-unique identifier to the name portion of the parent's email address for all student email addresses. You could do it in such a way that it could be stripped off when you wanted the "real" email address. There's actually some precedent for this kind of approach, per http://www.plankdesign.com/blog/2013/06/testing-infinite-unique-email-addresses-with-gmail/.
I'm looking for a way to add a drop down for a customer's address (during registration, editing, checkout, etc..) that indicates whether or not it is a Residential or Business address. I have spent hours going through tutorials but they are all out of date or poorly written. I have read 6 different ones telling me how to do the same thing 6 different ways. Can someone outline a simple process that you need to do in order to add a custom attribute to an address? I'm on Magento 1.6
Try something like this tutorial at Fontis: Know More About Your Customers - Adding Custom Signup Attributes
Whilst this was written for 1.3.2.4, most (if not all) is still relevant for 1.6. I've done a very similar thing by allowing a customer to choose the customer group they wish to belong to, by following these directions.
Oh, and there are some great comments on the post as well.
These tutorials should give you a good idea how to do what you want:
http://www.unexpectedit.com/magento/add-new-customer-attribute-onepage-magento-checkout
http://www.excellencemagentoblog.com/magento-adding-custom-field-to-customer-address
Best regards
I am making a site for a client and decided i would use code igniter.
The site essentially has two backends, one for designers, and one for a sales team. So after logging in, the user will be redirected to either
mysite.com/sales/
mysite.com/design/
The sales team for example can view orders, containers, products, therefore i need a controller for each of these.
mysite.com/sales/orders/
The sales need to be able to view, edit, delete certain orders...
mysite.com/sales/orders/vieworder/235433
Basically my problem is i dont have enough url segments to play with.
My thoughts on solving my problem
removing the orders, containers, products classes and making ALL of their methods as methods of the sales class, although this would mean a large number of methods and loading all models so it seemed kind of pointless.
removing the sales/designer classes and controlling what each kind of user has access to based on a user type stored in session data.
a way of having an extra url segment?
I appreciate any advice, I just dont want to get 3 weeks into the project and realise i started wrong from the beginning!
Use folders.
If you make a subfolder in /application/ called sales you can put different controllers in there:
/application/
/sales/
orders.php /* Controller */
/design/
Then in orders.php you will put your vieworders($id) method and so on, and you will be able to acces it with domain.com/sales/orders/vieworders/id.
You can also make subfolders in the /models/ and /views/ to organize your files.
Now, Access Control is something apart and it depends more in the auth system you are using.
Give the user/designer a privilege, a column in the user table for example, check the permission of the user at the beginning of the function, then prevent or execute it.
This would be the exact way i would do it.
Seems like you should have a look into the routing class. Might be a dirty solution but rerouting the sales/(:any) to something like sales_$1 would mean you'd make controllers with names like sales_orders.
Same for the design part.
(FYI: $routing['sales/(:any)'] = 'sales_$1'; should do the trick; see application/config/routing.php).