← Back to Upcase

POROs to build complex models


(Rikki Pitt) #1

Hey folks,

I’m looking for a spot of advice if anyone has a moment to help…

I have a Rails database back model that requires some attributes added from a related model. So I was thinking of creating a class to build and assign the attributes and return the real model to call save on in the controller.

Is there a clean way of doing the following that doesn’t require a method call? Or does this look roughly okay? Essentially, I’d like to get this extensive assignment code out of my controller while maintaining a Rails like feel (returning of errors etc).

Thanks!


def create
    @model = ComplexModel.new(params, @another_model).store!

    if @model.save
      render json: nil, status: :ok
    else
      render json: { error: @model.errors.full_messages }, status: :unprocessable_entity
    end
  end

Where ComplexModel is along the lines of:

class ComplexModel
  def initialize(params, related_model)
    @model = Something.new(params)
    @related_model = related_model
  end

  def store!
    model.some_id = related_model.some_id
    # Several other things go here
    model
  end

  protected

  attr_reader :model, :related_model
end

(Joel Quenneville) #2

It sounds like you’re creating what’s often called a “form object”. You may find these articles helpful:

There’s also a Weekly Iteration Video on the topic of form objects.

Is there a clean way of doing the following that doesn’t require a method call?

I’m not sure what you’re asking here? You want to avoid calling persist! manually and would prefer just to call save ? If so, the example in the Code Climate blog post should have you covered.