Rails - 装饰器内部验证

Rails - validation inside decorator

我遇到了一些问题。我有一个 rails 模型(mongoid)。

class User
  include Mongoid::Document
  include ActiveModel::SecurePassword

  validate :password_presence,
           :password_confirmation_match,
           :email_presence,

  field :email
  field :password_digest

 def password_presence
 end

 def email_presence
 end

 def password_confirmation_match
 end
end

我的目标是调用验证取决于我将使用的装饰器。假设我有两个装饰器:

class PasswordDecorator < Draper::Decorator
 def initialize(user)
   @user = user
 end
end

def RegistraionDecorator < Draper::Decorator
  def initialize(user)
   @user = user
  end
end

所以现在当我 create/save/update 我的用户对象在 RegistraionDecorator 中时,我想执行所有验证方法。

RegistraionDecorator.new(User.new(attrbiutes))

但是当我在 PasswordDecorator 中执行此操作时,我只想调用 password_presence 方法。

PasswordDecorator.new(User.first)

当我将验证移至装饰器时,它不会工作,因为它 class 与我的模型不同。

我怎样才能做到这一点?

尝试改用表单对象模式。

这是一个示例(来自真实项目),说明如何使用 reform

class PromocodesController < ApplicationController
  def new
    @form = PromocodeForm.new(Promocode.new)
  end

  def create
    @form = PromocodeForm.new(Promocode.new)

    if @form.validate(promo_params)
      Promocode.create!(promo_params)
      redirect_to promocodes_path
    else
      render :edit
    end
  end

  private

  def promo_params
    params.require(:promocode).
      permit(:token, :promo_type, :expires_at, :usage_limit, :reusable)
  end
end



class PromocodeForm < Reform::Form
  model :promocode

  property :token
  property :promo_type
  property :expires_at
  property :usage_limit
  property :reusable

  validates_presence_of :token, :promo_type, :expires_at, :usage_limit, :reusable
  validates_uniqueness_of :token

  validates :usage_limit, numericality: { greater_or_equal_to: -1 }
  validates :promo_type, inclusion: { in: Promocode::TYPES }
end

奖励:该模型不会触发验证并且在测试中非常容易使用。