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.
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.
Doctrine2 ORM have 2 technical ways to handle many-to-many associations :
1/ For a "simple" relation between 2 entities, and without additionnal attribute :
Use #ManyToMany associations between entities
In this case, the link table is used directly, without an association entity
2/ When link table introduces extra fields or more than 2 entities :
Use an association class, ie an "real" entity to map the link table
In this case, the direct ManyToMany association is replaced by OneToMany/ManyToOne associations between the participating entities
These 2 implementations are quite different.
But, in some cases, future business requirements can quickly need to change simple associations, by adding extra fields for example.
In this case, we must replace direct ManyToMany associations in existing entities by the second implementation and refactor affected code.
So, is it a good way to always use association entities to handle all
ManyToMany associations ?
Otherwise, what are the best practices for
choosing the good implementation and handle these kind of domain
model evolutions ?
If you have a good reason to belief that in the near future you will have extra properties on your ManyToMany join table then it's a good idea to make an entity out of precaution. If not then it's better to use the normal ManyToMany relationship. Then when a change is needed you can update your schema along with your code. If you try to follow the Single responsibility principle then you can avoid refactoring large amounts of code.
Given that I have a model that stores movies, what would be the best way to specify relationships such as movie sequels and prequels?
I'd like to access these relationships using simple accessors such as movie.sequels (which would return an ordered list of movies that are sequels to movie) and move.prequels.
I've considered using a has_many :through relationship with a secondary model but how would I maintain movie sequence?
Or could there be a better methodology entirely?
An easy way could be using an ActiveRecord plugin like acts_as_list which allows you to define ordering between different items. You'd need to add a field to use as a scope, such as saga, so the order is defined within movies which belong to the same saga.
https://github.com/swanandp/acts_as_list
The plugin provides handy methods lower_items and higher_items which would work like the sequels and prequels methods you are looking for,
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
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.