I am using simple-blog plugin in grails. i have code
class OodlesBlogEntry extends org.grails.blog.BlogEntry implements Taggable, Commentable{
Boolean isProtected = false;
}
def entries = OodlesBlogEntry.findAllByTag(params.tag.trim(), [max:5, offset:params.offset, sort:"dateCreated", order:"desc"])
And
entries.findAll { it.published }
these are working fine but the problem is i want to use both statement together so that it can give me perfect output. something like.
def entries = OodlesBlogEntry.findAllByTagAndPublishAndLocked(params.tag.trim(), true, false [max:5, offset:params.offset, sort:"dateCreated", order:"desc"])
But this statement is not working. please help me to solve this issue.
Error when i put both in one line.
| Error 2014-10-06 12:40:52,133 [http-bio-8080-exec-5] ERROR errors.GrailsExceptionResolver - InvalidPropertyException occurred when processing request: [GET] /blog/tagged/android
No property found for name [tag] for class [class com.oodles.blog.OodlesBlogEntry]. Stacktrace follows:
Message: No property found for name [tag] for class [class com.oodles.blog.OodlesBlogEntry]
Line | Method
->> 104 | methodMissing in org.grails.datastore.gorm.GormStaticApi
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 569 | byTag in com.oodles.blog.BlogController$$EOrtPHk8
| 198 | doFilter . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 53 | doFilter . . in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
| 49 | doFilter in grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter
| 82 | doFilter . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 270 | doFilter in com.planetj.servlet.filter.compression.CompressingFilter
| 1145 | runWorker . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . in java.lang.Thread
The reason for the error is that findAllByTag
is not a GORM dynamic finder. It's a method that is added by the taggable plugin to any domain classes that implement the Taggable
interface.
Because findAllByTag
is not a dynamic finder, you cannot combine it with other dynamic finders, e.g. findAllByTagAndPublish
.
When you install the taggable plugin, 2 additional classes are added to your domain, Tag
and TagLink
. The latter joins a tag with a domain object that has been tagged with it, e.g.
mysql> select * from tag_links limit 5;
+----+---------+--------+---------+-----------+
| id | version | tag_id | tag_ref | type |
+----+---------+--------+---------+-----------+
| 1 | 0 | 1 | 1 | blogEntry |
| 2 | 0 | 2 | 1 | blogEntry |
| 3 | 0 | 3 | 1 | blogEntry |
| 4 | 0 | 4 | 2 | blogEntry |
| 5 | 0 | 5 | 2 | blogEntry |
+----+---------+--------+---------+-----------+
You could certainly write an SQL query that would retrieve all the published, unlocked blog entries with a particular tag, but it wouldn't be pretty. You might even be able to use HQL, but personally I wouldn't bother. I understand that your current approach requires you to run 2 queries where only 1 should be necessary, but does this really matter? Unless you have hundreds/thousands of blog posts (which seems unlikely) it's not going to make much practical difference.
Alternatively, you could get all blog entries with a particular tag via:
def entries = OodlesBlogEntry.findAllByTag(params.tag)
Then you can do filtering out unpublished or locked tags, sorting, and pagination in Groovy code:
def filteredEntries = entries.findAll{ it.published && !it.locked }
def sortedEntries = filteredEntries.sort { it.title }
def max = 5
def offset = params.offset
// TODO check the size of sortedEntries and adjust the pagination params to prevent an
// IndexOutOfBoundsException
def entriesPage = filteredEntries.sort[offset..<offset + max]