Rails patterns and anit-patterns

Published on: January 20, 2025

Here's a bullet list to make it easier to understand.
  • Controllers 
    • can call only models
    • can call only services
    • cannot call helper - anti-pattern
    • cannot call rake task - anti-pattern
    • cannot call migrations - anti-pattern
  • Models 
    • can be used only in controller
    • can be used only in services
    • can be used in rake task
    • can be used in migrations
    • maybe in other models
    • cannot be used in views - anti-pattern
    • cannot be used in helpers - anti-pattern
  • Views 
    • cannot call model - anti-pattern
    • cannot call services - anti-pattern
    • can call only helpers
  • Helper 
    • cannot be used in model - anti-pattern
    • cannot be used in controller - anti-pattern
    • only for views

More detailed

  • Controllers 
    • Can call models and services, but it's generally recommended to keep business logic out of controllers and instead use service objects to encapsulate complex logic.
    • Should not call helpers, rake tasks, or migrations as these are outside the scope of the controller's responsibilities.
  • Models 
    • Can be used in controllers and services, but it's generally recommended to keep controller logic separate from model logic and instead use services to encapsulate business logic.
    • Can be used in rake tasks and migrations, as these are both part of the Rails framework and can access the model layer directly.
    • Should not be used in views or helpers, as this can create tight coupling between the view and the model layer.
  • Services 
    • Can call models and other services to implement business logic, but should not contain view-specific logic or interact directly with the controller layer.
    • Can be used in controllers and other services, but should not be used in views or helpers.
  • Views 
    • Should not call models, services, or controllers directly, as this can lead to a mix of responsibilities and make the code harder to maintain.
    • Can call helper methods to encapsulate view-specific logic, but these helpers should not contain business logic or interact directly with the model or controller layers.
  • Helpers 
    • Should only be used for view-specific logic and should not contain business logic or interact directly with the model or controller layers.
    • Cannot be used in models or controllers, as this can create tight coupling and make the code harder to maintain.
In general, it's important to keep the responsibilities of each layer in mind and strive for loose coupling between them. This can help make the code more modular, easier to test, and more maintainable over time.
Built with Mevin in 2 mins ⚡️