2013-04-11 19 views
5

Trong ứng dụng quản lý công việc của tôi, người dùng sẽ có thể lọc nhiệm vụ dựa trên: assignedTo, priority, status và/hoặc dueDateđộng tạo ra một truy vấn dựa vào thông số được truyền cho một bộ điều khiển

Tôi không chắc chắn về cách để tạo truy vấn động ở chỗ nó sẽ tạo truy vấn dựa trên các tham số có sẵn.

Ví dụ:

Nếu tôi có một URL như: task/index?assignedTo=1&status=2

tôi có thể xây dựng một truy vấn dựa trên chỉ có hai thông số này. Phương pháp tôi đang sử dụng để là

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

Tôi rõ ràng là không muốn thực hiện một phương pháp khô bằng cách viết ra mỗi truy vấn findAllBy cho mỗi sự kết hợp tham số URL có thể.

Có cách nào tốt để làm điều này trong grails?

+0

Đó là tầm thường để tạo ra tên cụ tìm bằng cách làm một cái gì đó như ''findAllBy $ {params.collect {k, v -> k.capitalize()} .join (' And ')}" ', nhưng làm thế nào để biết rằng' assignTo' sẽ nạp một cá thể 'User' và' trạng thái' nên tham chiếu đến một 'TaskStatus'? –

+0

Đồng ý, tôi không muốn làm như vậy. Nó cho một luận án vì vậy tôi muốn mã được càng sạch càng tốt. –

+0

Tôi có thể đề xuất truy vấn được đặt tên - http://grails.org/doc/2.2.1/ref/Domain%20Classes/namedQueries.html - sau đó bạn có thể lọc theo người dùng và trạng thái. Tôi nghĩ rằng họ đá! – marko

Trả lời

5

tôi quản lý để làm việc này bằng createCriteria như sau:

Tôi đang sử dụng giá trị 0 cho bất kỳ params nếu người sử dụng chọn 'Tất cả' cho rằng bộ lọc đặc biệt, do đó nó sẽ được bỏ qua từ nơi khoản, nghĩa là không có thông báo eq() cho tham số đó.

Một đoạn mã:

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 
} 
1

Tôi sẽ xem xét Plugin có thể tìm kiếm cho điều này (http://grails.org/plugin/searchable). Nó rất dễ dàng để xác định các thuộc tính của Task nên có thể tìm kiếm được.

7

Chúng tôi đã triển khai chức năng lọc trên lớp miền để thực hiện việc này. Tóm lại, bạn thêm các đoạn mã nhỏ của namedQueries vào lớp miền của bạn.

Ví dụ:

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 
      } 
     } 

    } 
} 

này cho phép khả năng lọc hạt mịn để bạn có thể xây dựng 1 danh sách phương pháp có sử dụng tất cả các phương pháp lọc và tùy thuộc vào những gì người dùng cung cấp cho như nhập namedqueries được liên kết với nhau.

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

Giải pháp của tôi cho một động ở đâu truy vấn khỏi 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) 
} 

này có những hạn chế của nó từ một URL như sau:

visit/index?query=client.status=='suspect';atHome==false 
Các vấn đề liên quan