3

Learning Groovy and Grails and I am trying to simplify some controllers by making a BaseController.

I define the following:

class BaseController<T> {

    public def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond T.list(params), model:[instanceCount: T.count()]
    }
}

Then I have the following:

class TeamController extends BaseController<Team> {
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    /*
    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond Team.list(params), model:[teamInstanceCount: Team.count()]
    }
    */
}

Every time I try to make a call to this, I get a MethodMissingException on T.count(). Why does Team.count() work, but when I try to use generics T.count() fail?

-- edit -- (Adding exception) No signature of method: static java.lang.Object.count() is applicable for argument types: () values: []

Thaldin
  • 283
  • 3
  • 15
  • more weird... why does T.list() work, but T.count() doesn't? If it's failing in a unit test, there was something about .count() not being mocked well. – billjamesdev Mar 05 '15 at 00:09
  • This is failing when I actually run the app... Haven't tried writing a test for it yet. – Thaldin Mar 05 '15 at 00:12

1 Answers1

3

T is a type. So this does not work as you expect it to be. You have to hold a concrete class (see Calling a static method using generic type).

So in your case it's easiest to also pass down the real class. E.g.:

class A<T> {
    private Class<T> clazz
    A(Class<T> clazz) { this.clazz = clazz }
    String getT() { T.getClass().toString() }
    // wrong! String getX() { T.x }
    String getX() { clazz.x }
}

class B {
    static String getX() { return "x marks the place" }
}

class C extends A<B> {
    C() { super(B) }
}

assert new C().x=="x marks the place"
Community
  • 1
  • 1
cfrick
  • 35,203
  • 6
  • 56
  • 68
  • This indeed was my issue. Now on to new ones that I am running into! – Thaldin Mar 06 '15 at 18:06
  • So as a follow up to this. I've gotten the create method to work as well as the index now using this method, but I can't seem to get anything working with a method that accepts an "instance" `def show(Team instance) { respond instance }` I have tried replacing Team with Class, T, Object... and I am just not getting it I guess with Groovy. When I debug, it never seems to even hit the method at all. – Thaldin Mar 06 '15 at 19:23