I'm working through the book Grails: A Quick-Start Guide and have come upon a problem. The book has me install the Blurb plugin, which seems to work, but states that we will be using it as if it were a domain class and using it a pre-existing controller. The code that I am to add to the controller looks like this
def blurb = Blurb.findByName("custom_${event.id}" )
if (!blurb){
blurb = new Blurb(name:"custom_${event.id}" , content:"" ).save()
}
When I do this I receive the same error in the IDE and the run output
'unable to resolve class Blurb' and I am directed specifically to this line blurb = new Blurb(name:"custom_${event.id}" , content:"" ).save()
Can anyone tell me what might be going wrong? I'm assuming the plugin is installed properly because if I try to access it's controller/action directly 'http://localhost:8080/TekDays/blurb/create' the plugin's provided view renders properly.
Thanks!
--
For reference I am using STS / Grails 1.3.7
Update 2011.05.12 7:45AM CST
I've attached a screenshot showing my project from the STS interface to show how my project is laid out in the event that it is package related as Burt indicated. The issue though is I'm not sure how do to the import statement so perhaps that screenshot will help.
Here is the current code in the Dashboard Controller.
package tekdays
class DashboardController {
...
}
I've tried adding the following lines per Burt's suggestion, but I obviously don't have it right
package tekdays
package my.package <--unexpected token: package
class DashboardController {
I tried changing out my with tekdays and default and both yield the same result.
Am I doing that wrong?
Thanks!
The Blurb class is in the default package, so if your controller is in a package you'll need to use a Groovy trick to access it:
package my.package
import Blurb as Blurb
class MyController {
def action = {
def blurb = Blurb.findByName("custom_${event.id}" )
if (!blurb) {
blurb = new Blurb(name:"custom_${event.id}" , content:"" ).save()
}
}
}
Related
I am writing an application with Xamarin.Android with MvvmCross. I want my Activity to inherit from MvxAppCompatActivity so that I can use fragments. Here is my base class:
public class BaseActivity<TViewModel> : MvxAppCompatActivity<TViewModel> where TViewModel : MvxViewModel
{
public new TViewModel ViewModel
{
get { return base.ViewModel; }
set { base.ViewModel = value; }
}
}
I get this error on the OnCreate of my Activity:
Failed resolution of: Landroid/support/v7/appcompat/R$drawable; Didn't
find class "android.support.v7.appcompat.R$drawable" on path:
DexPathList...
But if I change MvxAppCompatActivity to MvxActivity it works fine...why?
I downloaded your solution and tried to build the Android project. It fails with 18 occurrences of the same error:
error: No resource identifier found for attribute 'loginButtonBackgroundColor' in package ...
So after a little inspection of your solution, I did the following steps to solve your issue:
1) In login_screen.axml I saw you had this line:
xmlns:[YOURNAMESPACE]="http://schemas.android.com/apk/res/[YOUR PACKAGE]"
Which is unnecessary. After removing it, and changing the lines [YOURNAMESPACE]:loginButtonBackgroundColor=... to local:loginButtonBackgroundColor=... the build succeeds.
2) I saw some layout files are located inside the /drawable folder (button_round_corner.xml, input_box.xml and login_button.xml). I moved them to the /layout folder and fixed the issues the change produced (only two).
3) Made Setup class inherit from MvxAppCompatSetup.
4) Added a RegisterAttribute over the LoginButton control. So the class definition looks like this:
using Android.Runtime;
...
namespace Xxx.Droid.Components
{
[Register(nameof(LoginButton))]
public class LoginButton : FrameLayout, IMvxNotifyPropertyChanged
{
...
}
}
And that's it! Probably (2) was not necessary, but leaving it here just in case.
It could be several things but it is probably the lack of some android support packages. Mainly the lack of Xamarin.Android.Support.Design gives that error. So check if you have that added and if not add it and it should solve your problem.
If it doesn't it's highly likely you lack some other android support packages
I'm using grails 3.3.0 with rest api and gson views. I have the following setup...
Domain Class
package foo
#Resource(uri="/api/bars", readOnly = false, formats = ['json', 'xml'])
class Bar{
String firstName
String lastName
}
Controller:
package foo
class BarController extends RestfulController<Building>{
def show(){
respond Bar.get(params.id)
}
}
_bar.gson:
import foo.Bar;
model {
Bar bar
}
json {
name bar.firstName
}
_show.gson:
import foo.Bar;
model {
Bar bar
}
json g.render(template:"bar", model:[bar:bar])
directory layout:
/grails-app/views/
-----------------bar/
--------------------_bar.gson
--------------------_show.gson
This fails during build, test, compile and war with the following error:
Execution failed for task ':compileGsonViews'.
foo_bar_show_gson: 3: unable to resolve class foo.Bar
I followed the documentation but I cannot get around this. Please help!
I have the same issue, my problem got solved when I change the views-gradle version to the 1.2.7
classpath "org.grails.plugins:views-gradle:1.2.7"
After looking through github issues this seems to be caused by the rest profile and running on a Windows machine. If I start a new project using the web profile everything works fine.
Grails 2.3.6 here. I went into myapp/grails-app/controllers and manually added a new WidgetController.groovy class:
class WidgetController {
def fizz() {
redirect(url: "http://google.com")
}
}
Then I run my Grails app locally, and when I go to http://localhost:8080/myapp/widget/fizz I just get my custom "page does not exist" error page. No errors in the logs.
Note: I did not use the grails create-controller Widget command; I just added a new file manually. What is going on here and what can I do to fix it?
Try to add a blank fizz.gsp page to your view/widget and it will work.
I'm playing around with Grails/Groovy and have some straight Groovy code working that utilizes groovy-wslite. That code starts as such
send-request.groovy
#Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.0')
import wslite.soap.*
When I implement that into my Grails code and view the controller/action I get this
Error 500: Internal Server Error
URI: /FormProj/hello/trigger
Class: java.lang.RuntimeException
Message: No suitable ClassLoader found for grab
And here's the code in it's current state (I've tried a LOT of different things)
HelloController.groovy
package com.demo
import groovy.grape.Grape
class HelloController {
def index() { }
def sayHi() {
return [
greeting : "Hi there, ${ params.name }"
]
}
def trigger() {
Grape.grab(group:'com.github.groovy-wslite', module:'groovy-wslite', version:'1.1.0')
…
}
}
As I'm sure you notice I'm very green with Grails/Groovy and really all things Java. I do know there is a wslite plugin for Grails, but surely this can work too right?
Grails: 2.3.8
Groovy: 2.2.2
UPDATE
Based on Ian Robert's advice I have updated my BuildConfig file by adding this line to the dependencies block
compile 'com.github.groovy-wslite:groovy-wslite:1.1.0'
And updated my controller to look like this
HelloController.groovy
package ws.thejspot
import wslite.soap.*
class HelloController {
def index() { }
def sayHi() {
return [
greeting : "Hi there, ${ params.name }"
]
}
def trigger() {
def client = new SOAPClient('URL')
}
}
Unfortunately now the IDE, GGTS, shows an error in the controller 'unable to resolve class SOAPClient'
Rather than trying to download the dependencies with #Grab, you should use the standard Grails dependency mechanism - edit grails-app/conf/BuildConfig.groovy and look for the grails.project.dependency.resolution closure. Inside that, in the dependencies block you should add
compile 'com.github.groovy-wslite:groovy-wslite:1.1.0'
and remove anything Grape-related from the controller, leaving just the import wslite.soap.*
You will probably need to run
grails compile --refresh-dependencies
at least once to ensure that Grails picks up your change to BuildConfig - it deliberately doesn't do a full dependency resolve every time you compile, so as not to slow down the build too much, so you need to tell it to refresh when you know it needs to.
I'm following the code examples in 'The Definitive Guide to Grails' by Graeme Keith Rocher, and have come across a rather unusual stumbling block.
Essentially, 2 domain classes exist - Bookmark & Tag.
Bookmark:
class Bookmark {
static hasMany = [tags:Tag]
URL url
String title
String notes
Date dateCreated = new Date()
}
Tag:
class Tag{
static belongsTo= Bookmark
Bookmark bookmark
String name
}
I'm instructed to launch the Grails Console (is this the same as the groovy console)and create a new object as follows.
def b = new Bookmark(url: new URL('http://grails.org/'), title:'Grails', notes:'Groovy')
This results in:
Result: Bookmark : null
According to the book, GORM automatically provides an implementation of an addTag method. So I code...
b.addTag( new Tag(name: 'grails'))
Only to get whammed with the error message:
Exception thrown: No such property: b for class: ConsoleScript1
groovy.lang.MissingPropertyException: No such property: b for class: ConsoleScript1 at ConsoleScript1.run(ConsoleScript1:2)
The author hasn't accounted for this in the book. I was wondering if anyone could help me out?
Thanks.
Are you reading the 1st edition of the book? If so it's quite outdated. The add* methods have been deprecated since 0.5. It was replaced by addTo* so do this instead:
b.addToTags( new Tag(name: 'grails'))
Assuming your code example shouldn't have Bookmarks defined twice (copy and paste error?) and Tag might look like this:
class Tag {
String name
}
The groovy console is not the same as the grails console. To access the grails console, type grails console in your application directory - you should get a Java GUI app. It's possible that the example will work then because grails add some stuff to the standard Groovy.
Also, your problem isn't the addTag method, but the item b that you defined which cannot be found. Try entering the whole script into the console at once and executing it, instead of executing it line by line.