This is more of a conceptual question...
I'm starting on an app that will have a few roles (e.g. employee, manager, store_manager). Each role will view/edit/destroy in different ways from each other. When a manager is editing an employee the view will be very different than when a store_manager is editing.
My thinking was to namespace many of the models with the role. Like:
namespace :store_manger do
resources :users
resources :widgets
end
namespace :manager do
resources :users
resources :widgets
end
This seems to be a much cleaner method than creating all the if can? :update, #article all over the controllers and views.
So, is my thinking on track?
Are there any pitfalls to using this method that I need to be aware of?
Or, is there a better way to organize this?
You're correct, grouping different roles into the same view/controllers doesn't make much sense in this case since the views are all different. Even if you need to share views later on, you can just render the same layout.
Related
What is the best/standard way to create a relationship you can add to multiple dataobjects? using a DataExtension you can create a has_many like so
public static $has_many = array('Links' => 'Link');
but then in the mirrored has_one relation in Link you would have to explicitly list the classes using the DataExtension.
Use a many_many instead of as has_many.
Have a look at the File and Image classes to get an idea of how the framework does this. The framework's unit tests for those classes will also provide an indication for how they are set up and used.
I am currently going through Hartl's Rails Tutorial, and through the first 10 chapters or so have gotten used to the convention of putting most of the actions/methods in the controller. Currently, as the book is going through and defining a feed method for the Microposts, the method is placed with the User.rb model instead. As I am relatively new to the world of rails (and programming in general), I was wondering what the rationale or convention followed for putting this method (copied below) in the Model?
The method placed in the User.rb model:
def feed
# This is preliminary. See "Following users" for the full implementation.
Micropost.where("user_id = ?", id)
end
There is actually quite some contention on what code to put where, but in general, there are some easy guidelines to follow.
Does the method have to know some detail about the underlying data structure? Put it in the model.
An easy way to determine this is when it uses ActiveRecord methods like find, where, or specific columns in the database. By keeping this logic in the model, that means if you need to change the underlying datastore, you only have to change the model.
Does the method have some say in how a page is going to be rendered? Put it in the controller.
Generally, controllers should be pretty thin, pushing data to views and saving form data back to models.
While (if I remember correctly) Hartl does not take about non-rails classes, don't be afraid to put 'business logic' outside of the rails structure. You can create a app/lib or app/services or app/x directory and put plain old ruby objects in there, which can then be called from your controllers and models to handle those things they are good at.
Aim to 'push' things 'up' into the model as much as possible, then they will be repeated less and available to more. Don't just use models for Active Record database tables.
You can often unit test models easier.
Another 'next' place to put stuff that is shared is in /lib
I have a model that for edit/update actions only is logically split into two forms. The model is Venue. I created app/controllers/venues_controller.rb. The two sub-forms are Details and Policies, so I created app/controllers/venues/details_controller.rb and app/controllers/venues/policies_controller.rb, as well as their corresponding views. The child controllers do inherit from VenuesController. I added the venues namespace to my routes, so it now looks like:
resources :venues
namespace :venues do
:details, :policies
end
The routes work correctly, the correct views load, the "edit" action on the sub-controllers is called correctly. However, in the sub-views, I'm using the RESTful form_for(#venue), so when the form is POSTed (PUT) it is going to venue_path, not venue_details_path.
I looked at the docs for form_for and can't figure out a way to keep my sub-forms restful. You can add a token for a namespace a la form_for([:namespace, #model]), but in my case, the model name is the namespace, so it's inverted.
I really don't want to split the model itself, since that has other implications that would be harder to address.
So far, I see two solutions, both of which I don't like:
1. Let both views POST to VenuesController#update and deal with any differences there (more lame controller code)
2. Use form_tag and _tag helpers (more lame view code)
Am I missing something obvious? Is there something different I can do in the routes, or is there another way to call form_for?
I've scanned some posts about Presenter and Conductor patterns but they don't seem to fit this problem. I've read a few stackoverflow threads about whether creating two controllers for one model koscher (it is), but nothing about this specific issue.
Ah, found it. form_for(#venue, :url => venues_detail_path(#venue)). Gotta love Rails.
Suppose i have mapping table map_user_roles. I have defined models Role and User. Both are associated to each other by relationship has_and_belongs_to_many. Of course it does not make sense to define model for mapping table in rails.
I have defined users_controller and roles_controller for crud operations on user and role respectively.
For association of user-role, what should i do? Should i define separate controller like user_roles_controller or should i make modifications in Role and User controller(if so how to do so) ?
Please suggest, what is good practice. Examples and good links would be great help
Thanks for devoting time.
I don't see what a separate controller for the association would offer that couldn't be achieved with your existing UsersController and RolesController. Also, note that sometimes is does make sense to define a model for the mapping table, that's what the has_many :through association is for. You should use it if you need to store extra attributes against the join model.
I need perform some extra logic on an object before it is saved to the database. I would assume that using a before_filter would be the correct way to accomplish this, but I'm not sure how to pass the object to be saved into my before_filter method.
This is my first ever post here so go easy on me!
Theres a before_save method, in Rails 3 at least, that can be called in the model.
in Posts model
before_save :add_url_and_ID
def add_url_and_ID
#extra logic
self[:url] = whatever.com
self[:member_id] = member.id
end
I'm probably way off but its my first go!
That all sounds like model code to me. To get the most out of Rails (or any MVC framework) follow the 'Fat Models, Skinny Controllers' rule of thumb. It can be taken too far, but I think in this case it's pretty clear. If there are errors with the helper functions you mention, shouldn't the save action fail with appropriate error messages?
There's lots of good posts on SO on this subject. Here's one
If this doesn't give you enough to work with I'd suggest posting some code.