Correct way of applying REST in Rails 3 many User Types - ruby-on-rails-3

I want to apply REST to my Rails 3 application.
I understand the basics but am still a NOOB and would like some help or advice if this is correct.
I have a USER model. However I have three kinds of User, as in they have different roles in the application.
When I create say the Celebrant I need to do other things in the create action that are different then the things I need to to for the Manager which is again different from what I need to do for the Participant.
So I was thinking of creating three resources.
1.Celebrant - new create only
2.Manager -new create only
3.Participant. -new create only
This way I can have the three REST NEW and CREATE actions that are different from each.
Is this the best way to go about this?

A couple of thoughts…
1. DRY
If Celebrant, Manager, and Participant all extend User, then it's best to have 1 controller. Most of the code will be the same between the 3 controllers otherwise.
2. Fat Models, Skinny Controllers
The controllers just pass parameters to models, so really you should only have to call 1 method on the model in the controller, like User.create. This makes it so your controllers don't perform any logic, so you don't need 3 separate controllers.
Check out the inherited_resources gem to pretty much remove all code from your controllers.
Doing it like this, you handle what happens before/after create in each of your User model subclasses.
3. Using a Role model instead of User subclasses
I ran into your exact problem before. I started with 3 user classes. But I quickly wanted to do more with the roles, add more, blur the lines, etc. By having 1 User model which has_many :roles (there's role plugins out there), you can handle all your custom logic in your save callbacks in the user model based on roles. Now your controller is lean, and you don't have to manage 3 classes.
Hope that helps.

Related

Designing MVC Controllers

My question is about the process of designing an ASP.NET MVC site and specifically about determining what controller classes and action Methods my site should have.
This is what I understand so far about the process of designing an ASP.NET MVC web site:
First, I should use a mock-up tool such as Balsamiq to create a
mock-up, so I know how my site should look. This gives me the views.
Second (or concurrently), I model the objects of my domain.
Given the views and the model, how do I proceed with the controller classes and their action Methods? A controller can call different views, so what's my "factoring" criteria?
So, my question is: Given the views and the model, how do I decide what controllers to have and which action methods each should contain?
Imho, a controller should reflect a specific functional area, dealing with a group of features related to each other. For example, you can have a controller dedicated to user management, where you create and edit users, manage user rights, user profiles, anything related to your users, another controller for product management, where you display available products according to user inputs, manage stocks, suppliers, and such...
With too much controller you end up redirecting all day long, with too few controller it's a mess to maintain.
Of course, when i say"this controller manages that group of features", i don't say "put all your business logic here". Controller's duty is to call the right business method(s) and to pass this data to the right view.

How do I batch update my app database?

New to MVC and RoR and having a hard time grasping some of the concepts. One of them is batch updates to the database.
Lets say I have a set of data such as a list of students and their attributes like this
Student ID:1
Name: Alice
email:alice#alice.com
attribute: anything
attribute2: anything2
Student ID:2
Name: Kate
email:kate#kate.com
attribute: anything
attribute2: anything2
etc..
I've gotten the list from an API call.
I don't want them to be editable, nor do I want the attributes to be visible to the user.
Question is, how do I go about saving them into my database? It seems in the MVC way, each action requires a view? Will I be able to do it as a background process?
Thanks
Ryan
p/s- pointers to the right resources welcome too
So you'd just like to obtain records from an API and create models from them?
One option you may consider is writing rake tasks to get the data, and create the corresponding models (No rails answer is complete without a railscast link, so here's one It's old, but tells the basics)
Going this route, you could avoid making the data publicly editable, and just get it into the models/DB
You could use fixtures for this type of thing. Or, just use SQL to insert into your DB outside of Rails.
http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html

Rails 3 Dynamic User Roles/Access Levels

I'm developing an application that will be used by teachers to manage student assignments and submissions. However, different schools have different standards for assignment submissions, grades, what students should and shouldn't be able to do. As such, I was looking to implement some flexible role management functionality into my application so that the teachers can decide exactly what privileges the user should and shouldn't be able to perform.
One quick solution to this might be to simply add some boolean fields to my User model that the teachers can manipulate by way of check-boxes and run a before_filter on the pertinent controller actions. Alternatively I could move the role definitions to a separate model belonging to the teachers and run the before_filter on that.
Before I try to implement either of those solutions I was wondering if there were any gems or plug-ins that already handle flexible user-managed role definitions?
Just as a side-note I'm using Devise for my authentication if that means anything.
I found this gem quite useful. https://github.com/EppO/rolify
And it has a way of easy integration with Devise and CanCan https://github.com/EppO/rolify/wiki/Tutorial

Additional RESTful methods and actions DRY

I have a model that has several columns I want to present to the interface to update as different pages. My question deals with what is the best rails-y way to organize your routes and controller actions.
For example, a User has a "Profile" and a "Billing Address". Both pages contain columns only from the User model, they are required and one-to-one, and small, so an additional model seems like unnecessary overhead.
It seems like I have to add a GET and a PUT for each different view I want to present, is that right? So instead of just edit/update, I'd need edit_profile/update_profile and edit_billing/update_billing, etc.
Even without a Profile model, I think you still can use ProfileController and views for profile like 'views/update.html.erb', and make it route as '/users/123/profile/'.
In my opinion, we don't need to mapping every view or controller to one model strictly. Rails is based on ROA, but here the "resource" can be more abstract.

Attribute level authorization in Rails 3

I'm using devise for authentication and I'm looking for an authorization framework that lets me declare edit permissions for specific model attributes.
I have three different roles in my app: Teacher, Parent, and Student. The Student model belongs_to Family. When a Teacher creates a Student, they are able to set the Family association. When a Parent visits the edit page for a Student, however, they should not be able to change that association, only view it.
In the view, it's easy to alter the form depending on who is viewing it (disable or don't disable the family select input, for example) but a crafted form can get around that. What I need is something that will throw some kind of authorization exception when someone tries to change an attribute that they are not allowed to change.
I'm currently looking at declarative_authorization, but it seems it's not fine-grained enough to restrict changes to attributes, only the model as a whole.
I've ended up using the new MassAssignmentSecurity feature, although it looks like it might not work that great in conjunction with accepts_nested_attributes_for.
I realize my answer comes 2 years late. For what it's worth what you need is an authorization framework that is fine-grained enough.
XACML, the standard from OASIS provides just that. It can handle any number of attributes.
See my detailed answer here: Rails 4 authorization gem