Ruby on rails 轨道;验证服务对象中的参数
我在Rails中创建了一个服务对象来封装为Stripe()创建计划的业务逻辑。 对于服务对象,是否有处理参数验证的好模式 对于验证:Ruby on rails 轨道;验证服务对象中的参数,ruby-on-rails,Ruby On Rails,我在Rails中创建了一个服务对象来封装为Stripe()创建计划的业务逻辑。 对于服务对象,是否有处理参数验证的好模式 对于验证: 我必须检查所有输入是否为零或类型错误。有什么方法可以方便地验证吗?也许是铁路的延伸 这是一个例子 # app/services/service.rb module Service extend ActiveSupport::Concern included do def self.call(*args) new(*args).ca
- 我必须检查所有输入是否为零或类型错误。有什么方法可以方便地验证吗?也许是铁路的延伸
# app/services/service.rb
module Service
extend ActiveSupport::Concern
included do
def self.call(*args)
new(*args).call
end
end
end
# app/services/plan/create.rb
class Plan::Create
include Service
attr_reader :params
def initialize(params = {})
@params = params.dup
end
def call
plan = Plan.new(attrs)
return plan unless plan.valid?
begin
external_card_plan_service.create(api_attrs)
rescue Stripe::StripeError => e
plan.errors[:base] << e.message
return plan
end
plan.save
plan.update(is_active: true, activated_at: Time.now.utc)
plan
end
private
def external_card_plan_service
Stripe::Plan
end
def build_data_hash
{
id: params.fetch(:stripe_plan_id)
stripe_plan_id: params.fetch(:stripe_plan_id)
amount: params.fetch(:amount)
currency: params.fetch(:currency)
interval: params.fetch(:interval)
name: params.fetch(:name)
description: params.fetch(:description)
}
end
def attrs
build_data_hash.slice(:stripe_plan_id, :amount, :currency, :interval, :name, :description)
end
def api_attrs
build_data_hash.slice(:id, :amount, :currency, :interval, :name)
end
end
我试着使用Virtus()。
但是,我不知道如何在这种类型的服务对象中使用它
更新
# api/v1/controller/plans_controller.rb
module Api
module V1
class PlansController < Api::V1::ApiController
before_action :check_type, only: [:create]
def create
@result = Plan::Create.call(plan_info_params)
if @result.errors.blank?
resource = Api::V1::PlanResource.new(@result, nil)
# NOTE: Include all domains created within this routine.
serializer = JSONAPI::ResourceSerializer.new(Api::V1::PlanResource)
json_body = serializer.serialize_to_hash(resource)
render json: json_body, status: 201 # :ok
else
errors = jsonapi_errors(@result)
response = { errors: errors }
render json: response, status: 422 # :unprocessable_entity
end
end
private
def check_type
data_type = 'plans'
unless params.fetch('data', {}).fetch('type', {}) == data_type
render json: { errors: [{ title: 'Unprocessable Entity', detail: "Type must be #{data_type}" }] }, status: 422
end
end
def plan_info_params
params.require(:data).require(:attributes).permit(:stripe_plan_id, :amount, :currency, :interval, :name, :description)
end
end
end
end
#api/v1/controller/plans_controller.rb
模块Api
模块V1
类PlansController
是一个不错的解决方案
class PlanForm
include DryValidationForm
Schema = Dry::Validation.Form do
required(:stripe_plan_id).filled(:int?)
required(:stripe_plan_id).filled(:int?)
required(:amount).filled(:int?, gt?: 0)
required(:currency).filled(:str?)
required(:name).filled(:str?)
optional(:description).maybe(:str?)
end
end
end
可能调用表单的最佳位置是从控制器获取参数。然后将有效参数传递给服务对象谢谢您的回答。这里使用的是表单对象,对吗?另外,我不确定Form对象是否可以,因为我们一直在构建API。@TSH表单用于验证和准备参数,以便进一步处理。所以,是的,表单对象在这里是一个很好的选择,不管它是否用于API。谢谢!你觉得virtus+表单对象怎么样?我很想知道利弊。@TSH在我们的项目中,我们从基于virtus的表单(有gem
reform
)切换到了dry validation
,因为这更方便。然而,我不记得virtus有什么特别的问题。当表单变得复杂(嵌套对象等)时,会有一些麻烦。没什么不可能解决的,听起来不错。我一直在尝试添加它,但找不到任何应用内实现示例。如果您根据上面的示例向我展示如何在控制器中实现它,那将非常棒。我更新了我的问题!
class PlanForm
include DryValidationForm
Schema = Dry::Validation.Form do
required(:stripe_plan_id).filled(:int?)
required(:stripe_plan_id).filled(:int?)
required(:amount).filled(:int?, gt?: 0)
required(:currency).filled(:str?)
required(:name).filled(:str?)
optional(:description).maybe(:str?)
end
end
end