DEV Community

Augusts Bautra
Augusts Bautra

Posted on

POROs, in-memory Models and AR models, a continuum

AR models are great, abstract interaction with the DB away, get stuff done. But what if you want to practice clean coding and separate IO for different actors in your app? One way could be to set a virtual attribute and perform validations, pre/post-processing based on that. Lots of IFs and macaroni ensues. Trailblazer toyed with the idea of a "form object", a middle layer between user input and DB persistence. It's a good idea, and you can probably roll your own simple form objects.

Structure of form models

The two in-memory models, we could call them "form models" can be regular POROs, but perhaps it's more powerful to use Rails' model functionality, especially attribute API and validations:

class FormModel
  include ActiveModel::AttributeMethods
  attribute :attribute_name

  include ActiveModel::Validations
  validates :attribute_name, presence: true
Enter fullscreen mode Exit fullscreen mode

Naturally, you will need to implement the conversion functionality (the arrows in the image above) to transform valid form models into the persistable model. .save!, .to_some_model, and .attributes_for_some_model are possibilities.
Note that form models would not use STI at all, and can have attributes completely different than the model used to finally persist. Usually some subset will overlap tho.

Unfortunately, there's some difficulty with naming, namespacing and file placement. Ideally, we'd want to indicate that the two form models interact with the underlying AR model. For example, if we have Article as the AR model, what names and namespace(s) would we use for the form models? Perhaps the easiest would be to use Article::Actor1Form and Article::Actor2Form. This puts the cart before the horse a bit, but at least we have communicated the conceptual link.

Let me know what you think. Have you had an opportunity to use in-memory models, or even plain POROs when modelling your domain? What results did you have?

Top comments (0)