2013-04-11 9 views
5

W mojej aplikacji do zarządzania zadaniami, użytkownicy powinni mieć możliwość filtrowania zadań na podstawie: assignedTo, priority, status i/lub dueDateDynamicznie tworzenie kwerendy na podstawie params są przekazywane do kontrolera

nie jestem pewien, w jaki sposób utworzyć zapytanie dynamiczne, ponieważ zbuduje zapytanie na podstawie dostępnych parametrów.

Na przykład:

Jeśli mam URL takie jak: task/index?assignedTo=1&status=2

mogę zbudować kwerendę opartą tylko na tych dwóch parametrów. Metoda jestem przyzwyczajony jest

Task.findAllByAssignedToAndStatus(
    User.get(params.assignedTo), 
    TaskStatus.get(params.status) 
) 

I oczywiście nie chcą wdrożyć sucho przez wypisywanie każdy findAllBy zapytanie dla każdej możliwej kombinacji parametrów URL.

Czy można to zrobić w graalach?

+0

To trywialne, aby wygenerować nazwy znajdź robiąc coś jak '" findAllBy $ {params.collect {k, v -> k.capitalize()} .join ("And ')}", ale skąd wiadomo, że 'assignTo' powinno załadować instancję' User' i ' status "powinien odnosić się do' TaskStatus'? –

+0

Zgoda, nie chciałbym robić tego w ten sposób. Jest na rozprawę, więc chcę, aby kod był jak najbardziej czysty. –

+0

Może zasugeruję nazwane zapytanie - http://grails.org/doc/2.2.1/ref/Domain%20Classes/namedQueries.html - wtedy możesz odfiltrować według użytkownika i statusu. Myślę, że oni rocka! – marko

Odpowiedz

5

udało mi się uzyskać tej pracy przy użyciu createCriteria następująco:

Używam wartość 0 dla dowolnego params jeśli użytkownik wybierze „Wszystkie” dla danego filtra, dlatego zostaną pominięte where do tego parametru.

fragment kodu:

else 
    {  
     def assignedTo = Integer.parseInt(taskParams.assignedTo) 
     def priority = Integer.parseInt(taskParams.priority) 
     def status = Integer.parseInt(taskParams.status) 

     tasks = Task.createCriteria().list {    

      eq("project", Project.get(taskParams.PId)) 

      if(assignedTo > 0) 
       eq("assignedTo", User.get(assignedTo)) 

      if(priority > 0) 
       eq("priority", TaskPriority.get(priority)) 

      if(status > 0) 
       eq("status", TaskStatus.get(status))     
     }   
    } 
    return tasks 
} 
7

Wdrożyliśmy funkcjonalność filtr na zajęciach domen to zrobić. W skrócie dodajemy małe fragmenty nazwanych kwerend do klasy Twojej domeny.

Przykład:

class Employee { 

    String firstname 
    String lastname 
    Integer age 

    static constraints = { 
    } 

    static namedQueries = { 
     filteronFirstname { String inFirstname -> 
      if (inFirstname&& inFirstname?.size() > 0) { 
       ilike 'firstname', "%${inFirstname}%" 
      } 
     } 

     filteronLastname { String inLastname -> 
      if (inLastname && inLastname?.size() > 0) { 
       ilike 'lastname', "%${inLastname}%" 
      } 
     } 

     filteronAgeOlderThen { String ageOlderThen -> 
      if (age && age ?.size() > 0) { 
       gt 'age', ageOlderThen as Integer 
      } 
     } 

    } 
} 

To umożliwi precyzyjne zdolności filtracyjne drobnoziarnisty, dzięki czemu można zbudować 1 Wykaz metoda, która używa wszystkich metod filtracyjnych w zależności od tego, co użytkownik daje na wejściu namedqueries są połączone ze sobą.

Employee.filteronFirstname("John"). 
filterOnLastname("Doe"). 
filteronAgeOlderThen("10"). 
list(params) 
0

Moje rozwiązanie dla dynamicznego Gdzie zapytania z adresu URL:

if (params.query) { 
    def classLoader = getClass().getClassLoader(); 
    def query = new GroovyShell(classLoader).evaluate(
      "import myapp.Visit; Visit.where {$params.query}") 
    visits = query.list(params) 
} 

ten trwa jego ograniczeń z adresu URL jak poniżej:

visit/index?query=client.status=='suspect';atHome==false