Form Object: Cleaning Up Controller Logic in Ruby on Rails

Form Object: Cleaning Up Controller Logic in Ruby on Rails

In Ruby on Rails applications, we often need to process data that isn’t directly tied to an ActiveRecord model. When validation and processing logic is placed directly in the controller, it can make the code hard to understand and maintain. The Form Object design pattern can help solve this problem.

What is a Form Object?

A Form Object is a class that encapsulates validation and data processing logic. This allows controllers to stay clean and focused on their main responsibility. It promotes better separation of concerns and makes the code easier to maintain.

Usage example

Let’s consider a realistic scenario where we need to register a new user with an associated profile. The user must be validated, including checking for unique email addresses, and the profile can have a role (e.g., "client" or "admin").

Before: Controller with Validation Logic

Here’s how a controller might look before refactoring, with validation logic in the create method:


After: Using a Form Object

Now, let’s refactor the controller to use a Form Object. First, we’ll create the UserForm class, which will handle both the user and the profile:

Now we can simplify the controller:

Comparison: Before and After

Before

  • The controller had validation logic for both the user and the profile.
  • It checked for existing email addresses and added errors directly within the controller

After

  • The validation and creation logic were moved to the UserForm, simplifying the controller.
  • The controller now only interacts with the Form Object, promoting better separation of concerns.
  • Using ActiveRecord::Base.transaction ensures both operations are atomic, preventing data inconsistencies.


Conclusion

By using the Form Object pattern, we keep validation and processing logic separate from the controller, resulting in cleaner and more maintainable code. This pattern is a great way to promote good development practices in your Ruby on Rails applications, especially in scenarios with more complex business logic.



Antonio Fulgêncio

Senior Software Engineer | Front End Developer | React | NextJS | TypeScript | Tailwind | AWS | CI/CD | Clean Code | Jest | TDD

4 个月

Interesting!

回复
Elieudo Maia

Fullstack Software Engineer | Node.js | React.js | Javascript & Typescript | Go Developer

4 个月

Great article.

回复
Rafael Araujo de Lima

Senior Software Engineer | C# | .NET Core | ASP.NET Core | Azure | AWS

4 个月

Very Nice Rafael Aquino

回复
Otávio Prado

Senior Business Analyst | ITIL | Communication | Problem-Solving | Critical Thinking | Data Analysis and Visualization | Documentation | BPM | Time Management | Agile | Jira | Requirements Gathering | Scrum

4 个月

Insightful! Thanks for sharing Rafael Aquino ! ????

回复

要查看或添加评论,请登录

Rafael Aquino的更多文章

社区洞察

其他会员也浏览了