5

I'm trying to use findOrCreateBy to search for an object or instantiate one if I can't find one that matches, but it isn't working as I expected.

This is what I have:

String myBaz = "some unique string"
FooType myFooType = FooType.findByName("Large")

// The Foo table is empty, so this should give me a new Foo
Foo myFoo = Foo.findOrCreateByBazAndFooType(myBaz, myFooType)

assert myFoo.baz == myBaz 
assert myFoo.fooType == myFooType // Fails because myFoo.fooType is null, 
// but should be set to myFooType

What am I doing wrong? Why is the fooType not being properly set? Is this expected behavior or is this a bug in Grails?

cdeszaq
  • 30,869
  • 25
  • 117
  • 173
  • Well, it may be silly but since your database is empty, FooType.findByName("Large") will return null, right? And afterwards you create an object passing this null attribute. So, yeah, myFoo.fooType must really be null in this case. – Tiago Farias Jul 17 '12 at 17:09
  • @TiagoFarias, I updated the question to be more correct on this point. The FooTypes are bootstrapped into the DB, so it isn't truly empty, but there are no Foo objects in the DB. When `findOrCreate*` is called, `myFooType` is a persisted instance of `FooType`. – cdeszaq Jul 17 '12 at 17:15

1 Answers1

1

I'm not sure but it looks like you are trying to do this as a test. (based on your assert)

Dynamic methods added by Grails framework are not available in unit tests unless you mock the domain class. Now this is old grails code taken from another Question site but it may help

import grails.test.GrailsUnitTestCase   

class MessageControllerTests extends GrailsUnitTestCase {   

    def savedMessages   

    void setUp() {   
        super.setUp()   
        savedMessages = []   
        mockDomain(Message, savedMessages) //mocking the domain class   
        mockController(MessageController) //mocking the controller   
    }   

    void testMessageCanBeCreated() {   
        def messageController = new MessageController()   
        messageController.params.title = 'detail'  
        messageController.params.detail = 'some detail'  

        messageController.save() // executing the save action on the MessageController   

        assertEquals('list', messageController.redirectArgs.action)   
        assertEquals(1, savedMessages.size()) //assert the message has been saved   
    }   
}  
PJT
  • 3,439
  • 5
  • 29
  • 40
  • The asserts are only in there to show the problem. This is actually code from a service, so all of the GORM bits and bobs are there, but `findOrCreateBy*` just doesn't work correctly. Thanks though. – cdeszaq Jul 17 '12 at 18:36