2016-09-21 4 views
0

ドメインオブジェクトの予約には、オブジェクトがdbに保存された後に設定されるため、nullにすることができる複数の属性があります。 myService.actionのGrails rejectValue - ob.errorsを引き起こす複数のチェックnull

パート():

booking.properties = params  

if (booking.contactFirstname?.length() <= 1) { booking.errors.rejectValue("contactFirstname", "empty") } 
if (booking.contactLastname?.length() <= 1) { booking.errors.rejectValue("contactLastname", "empty") } 
if (booking.contactPhone?.length() <= 1) { booking.errors.rejectValue("contactPhone", "empty") } 
if (booking.contactMobile?.length() <= 1) { booking.errors.rejectValue("contactMobile", "empty") } 
if (booking.contactEmail?.length() <= 1) { booking.errors.rejectValue("contactEmail", "empty") }  

if (booking.hasErrors() || ! booking.validate()) { 
    return [success: false, model: booking] 
} else { 
    booking.save(failOnError: true) 
    return [success: true, model: booking]     
} 

私のコントローラが行う:予約、フィールド:私は hasErrors(豆使用してい

def result = myService.action(params) 
if (result.success) { 
    flash.success = message(code: "msg.successfullySaved") 
    redirect(action: "registerEventConfirmation", id: result.model.uid, params: [lang: params.lang], mapping: "paginated") 
} else { 
    flash.error = message(code: "msg.errorSavingCheckFields") 
    render(view: "registerEventStep3", params: [lang: params.lang], model: [booking: result.model]) 

'contactFirstnameを'、「HAS-エラー ')}

エラーフィールドをマークします。

テキストフィールドに値を指定せずにフォームを送信すると、すべてのフィールドが赤色になり、booking.errorsのエラーは> 0になります。

firstnameを付けてフォームを送信すると、booking.errorsはNULLになり、他のフィールドはマークされません。

これはバグですか?私は、Grailsの2.3.6

追加情報

  1. と思い、私はフォームを訪れ、それは私が赤ですべてのフォームフィールドを参照してください
  2. 完全に空に提出し、object.errorsは(> 0エラーがありますIは、再送信VALID)
  3. 私は赤、object.errors = 0エラー(INVALID)
  4. でフォームフィールドのどれを見ないFIRSTNAME最初のフィールドに値を入力し、
  5. を提出なしでのフォームは、私は赤ですべての空のフォームフィールドを参照してください
  6. を変更し、object.errorsは> 0エラー(VALID)

答えて

1

を持っている今、私は完全に状況を理解し、私は睡眠障害を持っていたので、ことを私は考えましたうまくいけば完全に理解し、物事を適切に使うことができるように、あなたには非常に簡潔な答えを与えてください。

まず、検証ビーンの作成は多くの作業になると思いますので、比較的簡単にそれを行う方法を教えてください、なぜ私の好みの方法なのか教えてください。

それは私の好ましい方法であるという理由だけであなたは最高のこの問題を解決する方法を説明するだから今

クラスMyController {

def myAction(Mybean bean) { 
    // 1. the object allowed into this save action 
    // are all that is available objects withing MyBean. 
    // If it has user define but not telephone. Then 
    // if telephone is passed to myAction it will fail and not recognise 
    // field 
    // When declaring Date someField or User user then the params now 
    // received as bean this way is now actually properly bound 
    // to the data/domainType declared. 
    // Meaning user will now be actual user or someField actually Date 
    } 

を行うとき。 Beanを作成する場合、単純にGrails 3

変更名/クラスでのGrails 2またはsrc/main/groovy/same/packagesrc/groovy/same/packageにあなたのドメインフォルダから実際のドメインクラスをコピーまたはBookingからBookingBeanへとコピーするので、それは別の名前を持っています。

それはすべてのオブジェクトが同一であり、この時点でコントローラから保存コピーされるので

であろう今のGrails 2における実際の BookingBean上方 @Validateableを追加またはGrailsの3

Class BookingBean implements Validateable {ようにメインクラスに実装を追加

class MyController { 

    def myAction(BookingBean bean) { 
     Booking booking = new Booking() 
     // this will save all properties 
     booking.properties = bean 
     booking.save() 
    } 
} 

しかし、あなたは特別な事情があり、私が代わりに何をするのか、メインのドメインクラスの過渡フィールドを宣言したかったが

class BookingBean { 
    def id 
    String contactFirstname 
    String contactLastname 
    boolean secondSave=false 

static constraints = { 
    id(nullable: true, bindable: true) 
    contactFirstname(nullable:true) //,validator:checkHasValue) 
    contactLastname(nullable:true) //,validator:checkHasValue) 
    secondSave(nullable:true,validator:checkHasValue)) 

} 

//use the same validator since it is doing identical check 

static checkHasValue={value,obj,errors-> 
    // So if secondSave has a value but contactFirstName 
    // is null then complain about contactFirstName 
    // you can see how secondSave gets initialise below 
    //typical set this to true when you are about to save on 2nd attempt 
    //then when set run validate() which will hit this block below 

    // Check all the things you think should have a 
    // value and reject each field that don't 
    if (val) { 
     if (!obj.contactFirstname) { 
      errors.rejectValue('contactFirstname',"invalid.contactFirstname") 
     } 
     if (!obj.contactSecondname) { 
      errors.rejectValue('contactSecondname',"invalid.contactSecondname") 
     } 
     //and so on 
    } 
} 
です

は、だから今、あなたのコントローラで:

class MyController { 

    def save1(BookingBean bean) { 
     Booking booking = new Booking() 
     // this will save all properties 
     booking.whatEver = bean.whatEver 
     booking.save() 


// you can choose to validate or not here 
// since at this point the secondSave has 
// not been set therefore validation not called as yet in the bean 

    } 

//あなたはおそらくIDを持っており、それは、実際のドメインクラス

def save2(BookingBean bean) { 

     booking.secondSave=true 
     if (!bean.validate()) { 
      //this is your errors 
      //bean.errors.allErrors 
      return 
     } 
     //otherwise out of that loop since it hasn't returned 
     //manually set each object 
     booking.contactFirstname=bean.contactFirstName 
     booking.contactSecondname=bean.contactSecondname 
     booking.save() 


    } 

}

E2Aのサイドノートと結合する必要があります - 上記答える必要があります

あなたが作成するまで検証しません。オブジェクトを作成してから値を追加した後にのみ、それを検証します。別の方法として、2番目のチェックの一環として実行する検証Beanに関数を作成することもできます。 This Example beanuntil formatRequestを検証していないas seen here

+0

私が作成したので、ドメインモデルが真のNULL可能ありオブジェクトを今すぐ保持してください。別のページに変更した後、私は特定のフィールドに検証を行いたいので、その後のフィールドを検証します。リクエスト時に余分なチェックを行うためにvalidate()でいくつかの引数を渡すことはできますか?フィールド上のあたりのよう – sullivan

+0

はNULL可能であり、それはValまたは値を持つ場合にのみ、その値を検証しようとします。要するに、現在値を保存せずに保存することができます。それは値を取得した瞬間、それはすなわちVALおよびval.lengthがある場合のように(ヴァル&& val.lengthは()<= 2){2未満次いで訴える場合従って設定checkHasValue検証に応じて検証しようとし。それはあなたが、これは論理的に聞こえるが、 – Vahid

+0

を行うために必要なものを行いますように聞こえる:1.作成:いくつかの値が提供されている場合、検証を有効にするべきではありませんが、オブジェクトの作成後に来る工程でオブジェクト、2。表示形式と検証。バリデーターは、値が渡されて長さに合わない場合にのみ起動します。 これはどのように作成しますか? – sullivan

1

は、私はあなたの質問の詳細を把握していないと呼ばれているので、私はちょうどこのに掘ってきたので、私はいくつかの一般的なガイダンスを提供します。

  1. validate()の前にhasErrors()をコールしないでください。そうした場合、Grailsはドメインの制約からエラーを受け取ることはなく、rejectValue()を使って自分で設定したエラーに終わるだけです。

  2. rejectValue()の使用には注意してください。ドメインの制約を使用してすべてのエラーを設定してください。洗練された制約がある場合はバリデータ構文を使用し、obj.getPersistentValue()はしばらくあなたの友人かもしれません。

  3. それでもrejectValue()を使用している場合は、(それ以降の呼び出しが検証することを理解しては)ゼロからスタートし、あなたの前にエラーが消去されます。私はあなたを保証することはできませんが、私はそれが100%OKです(自分のドメインオブジェクトに配置する)、このための回避策を書いた:

def validateWithErrors(def fields = null) { def existingErrors = this.errors def ret = (fields ? this.validate(fields) : this.validate()) existingErrors?.allErrors?.each { error -> this.errors.rejectValue(error.field, error.code) } return (existingErrors?.allErrors ? false : ret) }

+0

あなたのフィードバックのおかげで、私は#1と#3に完全に同意します。 #2私は部分的に同意し、2番目に投稿するコメントを参照してください、私はオブジェクトを保存した後に検証をしたいので、これはドメインモデルのバリデーターで解決できるとは思いません。 – sullivan

関連する問題