I have a grails project with a class that I can delete no problem when doing it "manually" from the controller. I use the following code.
def delete = {
def projectInstance = Project.get( params.id )
def employee = projectInstance.employee
def projectarray = new ArrayL开发者_如何转开发ist<Project>();
projectarray += employee.getProjects()
println("Size of projectarray is " + projectarray.size())
if(projectInstance) {
def rolearray = []
projectarray.remove(projectInstance)
def temp = new TreeSet<Project>();
temp += employee.getProjects()
temp.clear()
temp.addAll(projectarray)
employee.projects = temp
projectInstance.employer = null
projectInstance.delete(flush:true)
flash.message = "Project ${params.id} deleted"
redirect(action:"edit", controller: "employee", id: employee.id)
}
else {
flash.message = "Project not found with id ${params.id}"
redirect(action:list)
}
}
So that deletes a single instance fine.
Now i want to, from a different controller, remove ALL projects from an employee.
This is stored in the employee like so:
class Employee implements Comparable
{
static hasMany = [projects:Project]
static constraints =
{
}
static mapping = {
projects cascade:"all-delete-orphan", lazy:false
}
@XmlElementWrapper(name="projectslist")
SortedSet<Project> projects = new TreeSet<Project>(); // make a sortedSet?
}
So how would I now delete all projects from a particular employee instance?
I might be misunderstanding your question because I can't make sense of some of your code. It seems unnecessary. If your relationships are setup correctly (i.e. Project belongsTo Employee), this should be sufficient to delete a single project:
def delete = {
def projectInstance = Project.get( params.id )
projectInstance.delete(flush:true)
flash.message = "Project ${params.id} deleted"
redirect(action:"edit", controller: "employee", id: employee.id)
}
If this is a one-to-many, the next time you retrieve the employee the project will be gone. And this should work to delete all projects of an employee:
def delete = {
def employee = Employee.get( params.id )
employee.getProjects().clear()
employee.save(flash:true)
flash.message = "All projects of employee deleted."
redirect(action:"edit", controller: "employee", id: employee.id)
}
That assumes cascade:"all-delete-orphan". If that's not the case then you might need to also delete the instances and that might look something like this:
def delete = {
def employee = Employee.get( params.id )
// Make copy to avoid concurrent modification issues later
def copy = new TreeSet<Project>(employee.getProjects());
employee.getProjects().clear();
employee.save(flash:true)
copy.each{
$it.delete();
}
flash.message = "All projects of employee deleted."
redirect(action:"edit", controller: "employee", id: employee.id)
}
I'm not a groovy expert, so not sure if the copy is needed, or if you can just iterate on the collection directly. Seems like there is always a groovier way to do things. You might also want to check out the deleteFrom dynamic domain class method. That might be a more efficient grails approach depending on number of relationships to be deleted.
You could use the removeFrom* method that is generated by Grails when you declare the hasMany relationship - it's the equivalent of the addTo* methods:
def employee = Employee.get(params.id)
employee.projects.toList().each { employee.removeFromProjects(it) } // toList() prevents a ConcurrentModifactionException
精彩评论