2016-11-23 3 views
1

私はある種の問題に苦しんでいます。私はレールモデル(mongoid)を持っています。Rails - デコレータ内部の検証

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 

私の目標は、どのデコレータを使用するかによって異なります。私は私のユーザーオブジェクトが、私はすべての検証メソッドを実行したいと思いますRegistraionDecoratorの内側に更新/保存/作成したときに、今ので

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

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

:のは、私は2つのデコレータを持っているとしましょう。

RegistraionDecorator.new(User.new(attrbiutes)) 

しかし、私はPasswordDecorator内でそれを行います私はpassword_presence方法例えばコールします。

PasswordDecorator.new(User.first) 

検証をデコレータに移動すると、私のモデルとは異なるクラスが動作しません。

どうすれば実現できますか?

+0

'User'オブジェクトを任意のデコレータ内で呼び出さずに作成するとどうなりますか? –

+0

すべての検証メソッドが実行されますが、検証メソッドをより詳細に制御したいと考えています。 – mike927

+0

検証はモデルにのみ存在する必要があります。あなたはあなたのケースに合った 'field'や' attr_accessor'の値に基づいて実行する検証を決めることができます。 –

答えて

1

代わりにフォームオブジェクトパターンを使用してください。

ここでは、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 

ボーナス:モデルが検証およびテストで使用する多くの簡単なトリガーされません。

+0

素晴らしい、それは私が探していた解決策です。私は前に改革を知らなかった。ありがとう! – mike927