ruby-on-rails - 跨多(逻辑)层传递对象的 'Rails Way' 是什么?

标签 ruby-on-rails

我来自 .NET 世界,我正在尝试找出在多层应用程序中跨层传递对象的“Rails 方式”。

我正在编写一个多运营商定价 API。基本上在我的价格 Controller 中,我可以访问以下参数 参数[:载体] , 参数[:address_from] , 参数[:address_to] , 参数[:container_type] 等。我有一个验证库、一个合规库和一个价格查找器库,每个库都处理参数的一个子集。

在 .NET 中,参数将封装在数据传输对象 (DTO) 或契约(Contract)中。在调用任何库之前,它们将被转换为域对象 (DO),并且每个库都将在 DO 上工作,从而避免与 DTO 的紧密耦合。 Ruby 编程推荐使用“鸭子类型”,因此我的库可以直接处理参数(即使您将访问符号而不是对象/属性)。或者我应该将我的参数编码到 PriceRequest 对象并让我的库在 PriceRequest 类型上工作?

选项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

选项 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

最佳答案

您应该创建一个类型。我会用 事件模型 封装数据(属性)和业务逻辑(验证和一些特定层的数据处理方法)。

基本上,您希望能够在 Controller 中执行 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

希望能指出你正确的方向......

关于ruby-on-rails - 跨多(逻辑)层传递对象的 'Rails Way' 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36587215/

相关文章:

ruby-on-rails - 在 rails 3 中使用 --skip-active-record 选项创建项目后恢复 AR 支持

ruby-on-rails - 将 Rails 对象或变量传递给 Liquid

ruby-on-rails - 在此代码示例中,double splat (**) 参数是什么意思,为什么要使用它?

ruby-on-rails - 回形针 :style depending on model (has_many polymorphic images)

ruby-on-rails - Cucumber、rspec 和 Rails 3 引发错误选项 : --profile

mysql - rails : MySQL2 Error when hitting the finder of a model

ruby-on-rails - ActiveRecord:where 语句中关联模型的引用属性

ruby-on-rails - 如何调试 cucumber 测试?

ruby-on-rails - ActiveRecord 查询 : where a field is not true

ruby-on-rails - capybara + Rspec + Selenium : Page always blank in browser