What is the "Rails Way" for passing objects across multiple (logical) levels?

I come from the .NET world, and I'm trying to understand that the "Rails Way" passes an object through layers in a layered application.

I am writing an API API for several operators. Basically in my price controller, I have access to the following params [: carrier] , params [: address_from] , params [: address_to] , params [: container_type] options , etc. I have a validation library, a compliance library, and a price search library, each of which deals with a subset of the parameters.

In .NET, parameters will be encapsulated in data transfer objects (DTOs) or contracts. Before calling any of the libraries, they will be converted to domain objects (DOs), and each library will work with DOs, which will avoid hard communication with the DTO. Programming Ruby recommends using "duck typing", so my libraries can work directly with parameters (even if you refer to characters, not objects / properties). Or do I need to configure my parameters on the PriceRequest object and work with my libraries on the PriceRequest type?

Option 1:

class PricesController < ApplicationController
  def get
    CarrierValidator.validate(params)
    ...
  end
end

class CarrierValidator
  def self.validate(params)
    raise CarrierError if !Carrier.find_by_name(params[:carrier_name]).exists?
  end
end

Option 2:

class PricesController < ApplicationController
  def get
    pricesRequest = PricesRequest.new(carrier_name: params[:carrier_name], ...)
    pricesRequest.validate
    ...
  end
end

class PriceRequest
  attr_accessor : ...

  def initalize
    ...
  end

  def validate
    CarrierValidator.validate(self.carrier_name)
  end
end

class CarrierValidator
  def self.validate(carrier_name)
    raise CarrierError if !Carrier.find_by_name(carrier_name).exists?
  end
end

TIA,
J

+4
source share
1 answer

. ActiveModel () - ( , , ).

, Rails-y , :

def get
  price_request = PriceRequest.new(params[:price_request])

  if price_request.valid?
     # do something like redirect or render
  else
     # do something else
  end
end

:

class PriceRequest
  include ActiveModel::Model

  attr_accessor :carrier, :address_from, :address_to, :container_type

  validates :carrier, presence: true
  validate :validate_address_from

  def validate_address_from
    # do something with errors.add
  end

  # and so on

: http://edgeguides.rubyonrails.org/active_model_basics.html

API: http://api.rubyonrails.org/classes/ActiveModel/Model.html

, ...

+1

All Articles