I needed to create a custom join table to re-model a many-to-many mapping and following some great posts on here came up with the model below.
Now my question is, if I have either a Course or Journey object in a GSP, how do I access the extra column data belonging to the join table.
In this example, I want to access the field named extraColumn1 in the CourseJourneyDetail within my GSP if I have either a journey or course instance
I've tried the following :
${course.courseJourneyDetail.extraColumn1}
but it didn't work.
Here are (relevant parts of) my domain classes :
class Course {
static hasMany = [journies: CourseJourneyDetail]
String courseName
String organisersDescription
Set<Journey> getJournies() {
return CourseJourneyDetail.findAllByCourse(this)*.journey
}
}
class Journey {
static hasMany = [courses: CourseJourneyDetail]
java.util.Date dateCreated
java.util.Date lastUpdated
boolean enabled = true
User user
Set<Course> getCourses() {
return CourseJourneyDetail.findAllByJourney(this)*.course
}
}
class CourseJourneyDetail implements Serializable {
String extraColumn1
static belongsTo = [course: Course, journey: Journey]
boolean equals(other) {
if (!(other instanceof CourseJourneyDetail)) {
return false
}
other.journey?.id == journey?.id &&
other.course?.id == course?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (course) builder.append(course.id)
if (journey) builder.append(journey.id)
builder.toHashCode()
}
static constraints = {
}
static mapping = {
version false
id composite: ['course', 'journey']
}
}
Since you've established that each Course
/Journey
has a collection of CourseJourneyDetail
's rather than a single instance, ${course.courseJourneyDetail.extraColumn1}
won't work (as you've discovered).
If you break down your groovy expression into this: course.courseJourneyDetail
, it doesn't really make sense based on the relationships you have created. The reason being, Course
doesn't have a single CourseJourneyDetail
but rather a collection.
If your desire is to have Course
and Journey
in a one-to-one relationship, but with a join table with additional columns, then your domain structure needs to change to reflect this: rather than using static hasHany
in each class, you would switch to a single instance.
If your desire is to keep the many-to-many relationship, then you need to think about how to fetch the appropriate join object that represents the association. One example:
CourseJourneyDetail.findAllByCourseAndJourney(<courseInstance>, <journeyInstance>)
If you want the additional columns collected for all of the many-to-many associations, you can use a syntax that you are already using in your convience methods (getJournies
and getCourses
):
course.journies*.extraColumn1
This would output an array of Strings, so its usage makes less sense within a ${}
expression; and more sense within a g:each
. It entirely depends on how you plan on using this data.