请考虑the "Getting Started" guide中的此片段:
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
请注意title
和author
上的验证,这些验证位于控制器操作中。我的问题是:为什么这些验证是针对行动参数而不是Book
实体的?也就是说,假设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
实体上有缺点吗?
答案 0 :(得分:3)
官方指南中的Validations & Coercion部分解释了为什么您应该对您的请求进行验证,而不是对您的模型进行验证。
总结一下,以下是两个主要原因:
从架构的角度来看,永远不允许无效输入进入您的系统,因此最好在控制器级别完全跳过它们,而不是仅仅为验证创建模型,因为这是一个非常昂贵的操作
可以有多个请求在同一模型上运行。如果您在模型级别进行了验证,则还需要考虑这些请求的不同方案,这些方案同样是控制器的责任,而不是模型的。
尽管如此,如果您可以在业务逻辑中使用上述方案,那将归结为个人偏好。