Grails validateable not work for non-persistent domain class
Asked Answered
F

2

1

I followed the instruction here: http://www.grails.org/doc/latest/guide/7.%20Validation.html

and added into config.groovy:

grails.validateable.classes = [liningtest.Warm']

Then added in src/groovy/Warm.groovy (it's a non-persistent domain class):

package liningtest

import org.codehaus.groovy.grails.validation.Validateable


class Warm {
  String name;
  int happyCite;

  Warm(String n, int h) {
    this.name = n;
    this.happyCite = h;
  }

  static constraints = {
    name(size: 1..50)
    happyCite(min: 100)
  }
}

But it just doesn't work (both "blank false" & "size: 0..25") for the "hasErrors" function. It always returns false, even when the name is > 25.

Is this a Grails bug, if yes, is there any work-around?

I'm using Grails 1.3.3

UPDATE: I have updated the simplified code. And now I know that constraint "size" can't be used with "blank", but still does not work.

My test class in test/unit/liningtest/WarmTests.groovy

package liningtest

import grails.test.*

class WarmTests extends GrailsUnitTestCase {
  protected void setUp() {
    super.setUp()
  }

  protected void tearDown() {
    super.tearDown()
  }

  void testSomething() {
    def w = new Warm('Hihi', 3)
    assert (w.happyCite == 3)

    assert (w.hasErrors() == true)
  }
}

And the error I got:

<?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="1" failures="0" hostname="evolus-50b0002c" name="liningtest.WarmTests" tests="1" time="0.062" timestamp="2010-12-16T04:07:47">
  <properties />
  <testcase classname="liningtest.WarmTests" name="testSomething" time="0.062">
    <error message="No signature of method: liningtest.Warm.hasErrors() is applicable for argument types: () values: []
Possible solutions: hashCode()" type="groovy.lang.MissingMethodException">groovy.lang.MissingMethodException: No signature of method: liningtest.Warm.hasErrors() is applicable for argument types: () values: []
Possible solutions: hashCode()
    at liningtest.WarmTests.testSomething(WarmTests.groovy:18)
</error>
  </testcase>
  <system-out><![CDATA[--Output from testSomething--
]]></system-out>
  <system-err><![CDATA[--Output from testSomething--
]]></system-err>
</testsuite>

UPDATE 2: When I don't use Unit test, but try to call hasErrors in the controller, it runs but return false value. (hasErrors return false with Warm('Hihi', 3) ). Does anyone has a clue?

UPDATE 3: I followed Victor way, and now the problem is solved if I call validate() before hasErrors(). But I still don't understand, why "grails generate-all" controllers doesn't have to call validate() before using hasErrors()?

Floccule answered 15/12, 2010 at 9:45 Comment(4)
Did you call validate() before? Can we have whole action code?Orleans
And also the properties of the User class.Resect
I just call hasErrors() function, not validate(). Yeah, I will update the question soon.Surfboard
@Stefan Armbruster: I have updated the function. Please take a look.Surfboard
O
4

You really need to call validate() before - it will trigger validation and change object state. Looking at ValidationGrailsPlugin.addValidationMethods(), I see that hasErrors() is a read-only method.

Your sample worked for me after calling validate(). I tried in grails console (great tool, I highly recommend it!):

Warm w = new Warm('')
w.hasErrors() // 'Result: false'
w.validate()
w.hasErrors() // 'Result: true'

I added @Validateable to Warm class. I believe it makes no difference.

Orleans answered 22/12, 2010 at 13:50 Comment(5)
Yes, it works. But would you mind explaining why this happens? I mean, by the grails scaffold, they call hasErrors without any calling to validate()?Surfboard
I actually have no idea. Quick grep finds validate() or validateInstance() calls only in WebFlow plugin, not in ordinary scaffolding. But it's a fact.Orleans
Now I understand why it works. You may want to check #4545082Surfboard
Thanks. You mean that on persistent objects first phase validation triggers when assigning properties??Orleans
sorry, I don't get notified by your comment. No, it's like you said, hasErrors only has it meanings if you try to save or validate the object first.Surfboard
W
1

I don't think the validate() and hasErrors() dynamic methods are added in a Unit test. If you move this to an integration test they should be there.

Walkling answered 17/12, 2010 at 18:10 Comment(1)
Now I run hasErrors in the controller, and it doesn't report errors (when it should report). It means the methods exist, but they return the false value.Surfboard

© 2022 - 2024 — McMap. All rights reserved.