What type of logic should you put in a controller vs. model vs view
What are the best practices
Have you ever found yourself in a position when you want to implement a logic but can’t decide whether you should put it in a method in the Model or the controller or the view?
I had one such instance recently when I was trying to build my rails application that matches users with each other based on their preferences. This app had a User Model, a UsersController and a MatchesController. Here’s a simplified version of what’s happening in the application
User signs up through a form that asks them for their preferences about who they would like to meet. They also fill out details about themselves. This happens in the Users Controller.
Then, based on every user’s preferences, the application would find the best match for each user. I will create a
find_user_to_match()
function but where should I implement this function?
My options were to either do it in the Matches Controller so that it will be called by the #create action. Or to do it in the User Model.
How to determine which logic to put in the model and which to put in a controller?
Me: Can you give me a general idea of how to determine which logic to put in the model and which to put in a controller?
ChatGPT: Sure! In a Rails application, it's important to follow the Model-View-Controller (MVC) design pattern. The MVC pattern helps to separate concerns and organize your code, making it easier to understand and maintain. Here's a general guideline for each part of the MVC pattern:
Model: Models are responsible for handling the business logic and data manipulation. They interact with the database, encapsulate validations, and contain methods that operate on the data. In general, if the logic is related to the data, relationships, or rules specific to an object or a group of objects, it should be placed in the model.
Controller: Controllers are responsible for handling user requests, interacting with models, and rendering views. They act as an intermediary between the user interface (views) and the data (models). The controller's main job is to receive input, process it, and return the appropriate output (usually by rendering a view). In general, if the logic is related to handling user input, deciding which data to display, or selecting a specific view to render, it should be placed in the controller.
View: Views are responsible for displaying the data to the user. They contain the HTML, CSS, and minimal Ruby code needed to render the data. Views should not contain complex logic or data manipulation; those should be handled in the models and controllers.
How i implemented it for my case:
In the case of my matching logic, the correct decision was to place the find_user_to_match()
method in the User model is because it's related to finding a suitable match for a specific user, which is a data-related operation.
It involves calculating the similarity between users based on their preferences, filtering out already matched users, and returning the best match. All these operations are closely related to the data and the relationships between User instances. Therefore, it's more appropriate to place this logic in the User model.
On the other hand, the Matches controller is responsible for handling user requests related to the Match resource, such as creating new matches and displaying existing matches. It's not directly responsible for the actual matching logic, which is why the find_user_to_match()
method should not be placed in the controller.
Rules of thumb to decide where to place logic
In summary, when deciding where to place logic, ask yourself:
Is it related to data manipulation or business rules? Put it in the model.
Is it related to handling user requests or deciding which view to render? Put it in the controller.
Is it related to displaying data? Put it in the view.