在Hanami中实现表单对象

时间:2016-02-01 17:20:58

标签: hanami

在Bob的叔叔干净的架构中,Hanami受到启发,Form Objects保护Interactors和我们的交付机制(通常是一个http端点)之间的界限。

在Hanami文档中,使用Actions(see here)中的params块来完成边界防护。这似乎将验证与http传递机制相结合。对我来说,形式对象(或完成同样事情的黑色参数)将存在于与传递机制无关的交互者中似乎更自然。

不幸的是,我无法弄清楚Hanami是否支持这样的设计。我在Hanami论坛上找到similar question,但没有答案。

为了澄清,下面是一段代码,展示了我想要做的事情,但是使用VirtusActiveModel::Validations而不是Hanami设施。对于那些熟悉Trailblazer的人来说,其操作中的contract块(它的Interactor术语)是另一个例子。

最后,我是否误解了Hanami的用途? Hanami支持Interactors,所以看起来这应该是可能的......

require 'hanami/model'
require 'active_model'
require 'virtus'

class PersonForm
  include Virtus.model
  include ActiveModel::Validations

  attribute :name, String
  attribute :age, Integer

  validates :name, :age, presence: true

  def each
    attributes.each {|a| yield a}
  end
end

class Person
  include Hanami::Entity
  attributes :name, :age
end

# Code like this would then live inside of an Interactor, which
# can accept a params hash.

jonah_form = PersonForm.new({name: 'Jonah', age: '99'})
jonah = Person.new(jonah_form) if jonah_form.valid?
p jonah #=> <Person:0x007fbdde1edcc0 @id=nil @name="Jonah" @age=99>
# do stuff with our jonah entity

1 个答案:

答案 0 :(得分:1)

抱歉错过了这个问题。

params充当验证器以保存开发人员以创建和实例化另一个类。在Ruby社区中,这是一个问题。

DSL拯救这种妥协。

如果您希望拥有一个具体的表单对象,而不是使用ActiveModelHanami::Validations,则可以包含package com.mypackage.xdmodule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.integration.annotation.MessageEndpoint; import org.springframework.integration.annotation.Transformer; import org.springframework.messaging.converter.MessageConversionException; import org.springframework.util.StringUtils; @MessageEndpoint public class CustomProcessor { private static final Logger logger = LoggerFactory.getLogger(CustomProcessor.class); @Transformer(inputChannel = "input", outputChannel = "output") public String transform(final String payload) { if (StringUtils.isEmpty(payload)) { logger.error("payload is empty"); throw new MessageConversionException("payload is empty"); } logger.warn("log|warn: {}", payload); logger.debug("log|debug: {}", payload); return payload.toUpperCase(); } } 并具有相同的行为。