Question

The problem lies with linking a Event Instance to a Tag Instance. Upon Saving an event which has now been achieved ...but with design problems remaining, as one tag can be related to multiple events, and one event can have 0 to many tags.

In the standard save() method, I call within a method tagInput(), which takes the string from the form tagsCollection field (see screenshots) which separates the words and creates/saves an instance of the Tag (see method below). Each separated value is linked to the logged in user and now to the event the event.

The overall issue is how can I add more than one event instance id to each of the tags created, so that the event_id in Tag database is not overwritten with a newer event using the same tag name.

Demo of multiple tags separated via comma & Result of tags on webpage & Database: dbconsole

User Class (Used with Grails Security Plugin)

static hasMany = [tags : Tag]

Tag Class (for use with Tag Cloud Grails Plugin)

String tag
int times
User user
// Think this needs changing to hasMany i.e. many tags, many events linked to a tag
static belongsTo = [event: Event]

Event Class

String tagsCollection
User user
static hasMany = [tags: Tag]

.

So now an event id is being saved to a Tag instance but is problematic with re-using the same tag for the same user, as it needs to have the possibility of having multiple related event id's for searching abilities.

def tagInput(Event e) {
    //Stores tags sperated via comma in an array from the eventInstance tagCollection string field
    def tagArray = e.tagsCollection.replaceAll("\\s+","").toLowerCase().split(",")

    tagArray.each { aVar ->
        def splitTag = Tag.findByTag(aVar)
        //If the tag already exists for the current user logged in
        if (Tag.findByTag(aVar) && splitTag.userId == lookupPerson().id) {
        //Lookup person spring security method
        //+1 to how many times that tag has been used
            splitTag.times++

            //TODO IMPLEMENT A WAY TO APPEND EVENT ID TO TAG EVENT_ID FIELD

            splitTag.save(flush: true, failOnError: true)
        }  else {
            //if tag doesn't exist, create a new one using current logged in user
            def nTag = new Tag(tag:aVar, times: 1, user:lookupPerson())
           //SUGGESTION to save event id to a tag
            e.addToTags(nTag)
            e.save()
            //Set a user to own this tag
            def u = User.find(lookupPerson())
            nTag.save(flush: true, failOnError: true)
            u.addToTags(nTag)
            u.save()
        }
    }
}

(To test I used one user, with the first event who created 5 tags SEE DATABASE SCREENSHOT, then created a second event with the same user, and used two tags previously created in the last event t1 & t5 )

Was it helpful?

Solution

[So you are creating an event, and you may need to create new tags along with it.

So in order for you save to cascade to the tag as well, you have to define a belongTo on the tag class:

class Tag {
...
static belongsTo = [Event, User]
}

Now you can say:

Event event = new Event(...)
event.addToTags( new tag(...) )

And event.save() should also save your new tag.

Edit: Your new Tag should probably be something like Tag.findOrCreateByUserAndTag(user, name). This will find the tag if it already exists, and if it doesn't it will create it. Obviously replace the user and name variables with what you are working with.

OTHER TIPS

how can I add an event instance id to each of the tags created, when the id hasn't been created yet ...

You can't, and you don't need to do it either. By definition Tag instances does not require an Event instance reference because there is no Event property contained in the domain class.

So you can just create the tag instances and save it without a event instance persisted: simply return the saved tagInstances list from tagInput() method. Back in save() method, after you save eventInstance, add the tag list to it with something like this:

tagInstancesList.each{tagInstance->
    eventInstance.addToTags(tagInstance)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top