3

考虑“入门”指南中的这个片段:

module Web::Controllers::Books
  class Create
    include Web::Action

    expose :book

    params do
      param :book do
        param :title,  presence: true
        param :author, presence: true
      end
    end

    def call(params)
      if params.valid?
        @book = BookRepository.create(Book.new(params[:book]))

        redirect_to '/books'
      end
    end
  end
end

注意 和 上的验证titleauthor它们存在于控制器操作中。我的问题是:为什么这些验证是在动作参数上而不是在Book实体上?也就是说,假设验证on Book,您可以编写如下内容:

def call(params)
  book = Book.new(params)
  if book.valid?
    @book = BookRepository.create(Book.new(params[:book]))

    redirect_to '/books'
  end
end

并完全摆脱params障碍。这对我来说似乎更自然,并且会促进在不同操作中更容易地重用验证。

params我没有看到的方法有优势吗?将验证放在Book实体上是否有缺点?

4

1 回答 1

3

官方指南中的验证和强制部分解释了为什么你应该对你的请求进行验证,而不是对你的模型进行验证。

总结一下,主要有两个原因:

  1. 从架构的角度来看,不应允许无效输入进入您的系统,因此最好在控制器级别完全跳过它们,而不是创建仅用于验证的模型,因为这是一项非常昂贵的操作。

  2. 可以有多个请求在同一个模型上工作。如果您在模型级别进行验证,您还需要考虑这些请求的不同场景,这也是控制器的职责,而不是模型的职责。

不过,如果您可以在业务逻辑中处理上述场景,那将归结为个人喜好问题。

于 2016-02-01T09:55:07.533 回答