The Basics of MVC in Rails: Skinny Everything

Share this article

The Basics of MVC in Rails: Skinny Everything
head1

Model-View-Controller (MVC) is a design pattern for structuring software systems. The MVC pattern separates application logic from the user interface. MVC stands for Model, View, and Controller, the three main components of the MVC web application architecture. Each of these components should operate as discrete units. The discrete nature of MVC components is crucial for app maintenance and testing.

We often hear that the best way to write clear and concise code in Rails is by following the “Fat Models and Skinny Controllers” approach, which refers to how the Model and Controller in an MVC architecture should ideally work together. Having a “skinny” Controller (which is common practice) means that all non-critical logic moves to the Model; this simplifies testing and maintenance. However, we suggest taking the “skinny” approach a step further: put both your Models and your Controllers on a diet. Often we focus on Models and Controllers, but what about the View? The View can also be “fat,” and in fact, we believe that the View also should go on a diet.

What is the Function of Each MVC Component?

image00

To get a clear understanding of why we should keep all MVC components skinny, we first need to clarify what each of these components is responsible for.

Models

The Model is a layer between a database and an application that stores business logic related to a specific entity. Each Model is responsible for a different entity, and for connecting this entity with other entities. Models are usually invoked by Controllers.

For example, let’s say that a user wants to sign up. To do so, they must enter their email, a username, and a password. All these attributes are received by a Controller, which tries to create a new user (within the MVC architecture, this user is conceptualized as a ‘Model Record’). The Model runs validations: it checks whether the email entered is in the correct format, whether the password is secure enough, and whether the email and login are unique. If validation is successful, the Model then persists data to the database and a after_save callback is triggered. An example of a callback is a notification email that’s sent to a registered user and to an admin. If validation fails, the Model returns an error object that can be rendered and shown to the user.

Controllers

Controllers are responsible for reading input data (requests), choosing appropriate actions (business actions), and returning the resulting output data (responses).

For example, a Controller receives data from a client, and the router chooses an appropriate action in the existing Controller. On the basis of the received parameters, the Controller performs the following actions:

  • Authentication, when the Controller checks if a logged-in user is working with an app at the moment
  • Authorization, when the Controller checks whether a user is authorized to perform an action
  • Filtration of input parameters (permitted_attributes), when an action controller provides an interface for protecting attributes from end-user assignment.
  • Calls methods in Models or services.
  • Determines which format to give information to a client (JSON, HTML, PDF, XML) and selects the right View.

Views

A View is a visualization of the attached Model state. Put simply, a View is what the user sees. It’s the only MVC component that users interact with directly.

For example, a Controller chooses a template to represent user posts and inserts it into the proper layout. The View displays user information and contains some HTML elements, such as links to posts and a form for creating new posts.

What Happens If an MVC Component Does Someone Else’s Work?

  • It becomes difficult to maintain code in cases when the Controller contains large methods that perform unrelated actions.
  • Testing becomes almost impossible, as writing Unit Tests means testing concrete classes and modules that are responsible for specific functionality. It’s difficult to track a chain of method calls in “spaghetti code” (tangled code that includes a lot of unstructured and difficult objects and methods).
  • Every class should be responsible for a single part of the total functionality provided by the software. But often Controllers start including business logic that doesn’t belong or even forms of View logic. Model can end up including logic that isn’t related to persistence, and Views can contain calculations that aren’t welcome there at all.

The main rule we must follow to avoid fat MVC components is summed up as follows: “Everyone should mind their own business.”

How Can You Make MVC Components Skinny?

To achieve skinny Models, Views, and Controllers, we have to constantly refactor. Refactoring is a process of restructuring existing code. While refactoring doesn’t change anything from the perspective of the end user, it helps keep code clean, maintainable, and easy to test, which is beneficial for developers.

Refactoring is following the simple principle that if you make a mess, you should clean up after yourself. Refactoring is the constant cleaning up that happens after all code changes. You can’t build a skyscraper or paint a masterpiece without a lot of mess in the process, and it’s the same with writing quality code. That’s why we need to refactor each time we implement a new feature.

We can use various design patterns to aid us in the refactoring process, including:

  • Service Objects (and Interactor Objects)
  • Value Objects
  • Form Objects
  • Query Objects
  • View Objects (Serializer/Presenter)
  • Policy Objects
  • Decorators

To get a better understanding of how refactoring works and when it’s necessary, we’ll highlight some practices we often use at RubyGarage in the next post.

Frequently Asked Questions (FAQs) about MVC in Rails: Skinny Everything

What does “Skinny Everything” mean in the context of MVC in Rails?

“Skinny Everything” in MVC (Model-View-Controller) in Rails refers to the practice of keeping all components of the MVC architecture – the models, views, and controllers – as lean as possible. This means that each component should only contain the code that is absolutely necessary for its specific function. This approach promotes better organization, easier maintenance, and improved scalability of the application.

How does the “Skinny Everything” approach differ from the “Fat Model, Skinny Controller” approach?

The “Fat Model, Skinny Controller” approach suggests that most of the business logic should be placed in the model, leaving the controller as thin as possible. On the other hand, the “Skinny Everything” approach advocates for distributing the logic evenly across all components of the MVC architecture. This can lead to more modular and maintainable code.

What are the benefits of using the “Skinny Everything” approach in Rails?

The “Skinny Everything” approach in Rails can lead to cleaner, more maintainable code. By keeping each component lean, it becomes easier to understand what each part of the application does. This can also make it easier to test and debug the application, as there is less complexity in each individual component.

How can I implement the “Skinny Everything” approach in my Rails application?

Implementing the “Skinny Everything” approach in Rails involves careful planning and organization of your code. You should aim to keep each component of your MVC architecture – the models, views, and controllers – as lean as possible. This might involve breaking down complex methods into smaller, more manageable ones, or moving shared code into modules that can be reused across different parts of your application.

Are there any potential drawbacks to the “Skinny Everything” approach?

While the “Skinny Everything” approach can lead to cleaner, more maintainable code, it may also require more initial planning and organization. Additionally, if not implemented carefully, it could lead to code duplication or a lack of clear responsibility among components.

What are some best practices for implementing the “Skinny Everything” approach in Rails?

Some best practices for implementing the “Skinny Everything” approach in Rails include keeping methods short and simple, avoiding code duplication by using modules and mixins, and ensuring that each component of the MVC architecture has a clear, defined responsibility.

Can the “Skinny Everything” approach be used in conjunction with other design patterns in Rails?

Yes, the “Skinny Everything” approach can be used in conjunction with other design patterns in Rails. For example, you might use the “Skinny Everything” approach alongside the Service Object pattern, which involves creating simple, reusable objects that encapsulate specific business logic.

How does the “Skinny Everything” approach affect the performance of a Rails application?

The “Skinny Everything” approach can potentially improve the performance of a Rails application by reducing the complexity of the code. This can make the application easier to optimize and can lead to faster execution times.

How does the “Skinny Everything” approach affect the scalability of a Rails application?

The “Skinny Everything” approach can improve the scalability of a Rails application by making the code more modular and easier to maintain. This can make it easier to add new features or scale up the application as needed.

How can I learn more about the “Skinny Everything” approach in Rails?

There are many resources available online to learn more about the “Skinny Everything” approach in Rails. You might start by reading articles and tutorials, participating in online forums, or taking online courses. Additionally, practicing this approach in your own projects can be a great way to gain hands-on experience.

Viktoria KotsurenkoViktoria Kotsurenko
View Author

Viktoria Kotsurenko is a technical writer at RubyGarage and a fan of Ruby and Rails. She loves writing about web development, web design, testing, and other tech topics. Outside of the office, Viktoria rides her bike and takes walks in the evenings.

GlennGmvcRuby on Rails
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week