How to get grails to assign Id to a legacy Java object - grails

I have a java annotized domain object that I want to use in grails, this works fine, however all the generated templates use Id as the primary key. I tried to create a XxxConstraints.groovy file in the same package as my domain object, and added
mapping = {
id type:'assigned', name:<name of java field>, type: string
}
but that does not seem to work.
The error I get when trying to render the gsp is "class XYZ does not contain field id"
By the way I am using grails 2.1.0.
Thanks for the help in advance.

If you're talking about scaffolding views, they just have id field hardcoded, like: <g:hiddenField name="id" value="\${${propertyName}?.id}" /> (sample from edit.gsp).
Just modify your GSPs by hand to use your key field.
If it's more than one class and you don't want to generate all the views, you can install the templates into your project sources with grails install-templates and modify those to use your PK field. Maybe Groovy wrappers for Java classes will have ident() method, though not sure.
After looking at the doc, I'm in doubt if mapping{} DSL will work at all. Looks like only constraints section will work, and I believe you only need #Id annotation.

Related

Easiest way to render an Integer without thousands separator when using Fields plugin 2.0.2

I'm building a very basic app using Grails 3.0.2.
I have a domain class called Unit which contains, among others, a field called season, whose type is Integer and represents a year.
I have used the command generate-views to generate the scaffolded views.
Once running the application, when an existing instance is shown, the season is displayed using "," as thousands separator, and I want to remove it.
What is the easiest way to override (only) the format of the season?
For testing purposes, I have modified the show.gsp of the Unit class in the following manner:
<f:with bean="unit">
<f:display />
<f:display property="season" />
</f:with>
The <f:display property="season" /> displays simply "1,975", but ignores the label.
I've tried to understand the documentation of the Fields plugin, but I do not achieve what I want so it's obvious that I do not understand it.
I have added _displayWidget.gsp under views/_fields/unit/season (I have also tried under views/unit/season), but the outcome is exactly the same than before, so I assume the plugin is not taking them into account.
<g:formatNumber groupingUsed="false" number="${value}" />
I am not familiar with the _displayWidget.gsp convention, but a simpler approach might be to override the display of the unit.season property by adding a _display.gsp under views/_fields/unit/season containing just the following:
${value}
Diego, you can format any given number using the taglib formatNumber:
https://grails.github.io/grails-doc/latest/ref/Tags/formatNumber.html
Use the param 'format' and check the DecimalFormat patterns to find the one that suits fine for you.
Hope it helps!
I was able to get this working in Grails 3.1.14 by creating views/_fields/myDomainClass/myFieldName/_displayWrapper.gsp and containing a single line of ${value}

grails #Resource Annotation before Domain class

When I create a RESTful API in Grails, I add #Resource(uri='env',formats=['multipart/form-data'] before the domain class. And then use grails generate-all domain_name to generate the controller and view.
However, in Eclipse there is an Java problem like
The project was not built due to "RequestEnvironmentController$_on_closure51 [in [Working copy] RequestEnvironment.groovy [in test.environment.manager [in grails-app/domain [in restful-api-for-tem]]]] does not exist". Fix the problem, then try refreshing this project and building it since it may be inconsistent.
Then I get rid of the annotation and the error disappears and the post method still works. I am confused, is the annotation necessary or not? If it is necessary, how can I remove the Java error?
When you use the #Resource annotation there is no need to create a controller because this will be automatically generated as per documentation
Simply by adding the Resource transformation and specifying a URI,
your domain class will automatically be available as a REST resource
in either XML or JSON formats. The transformation will automatically
register the necessary RESTful URL mapping and create a controller
called BookController.

grails database-migration - can it generate for 'not null with default'?

What seems to me to be a common requirement for database changes, is the addition of a column that can't be null. One way round the problem of populating this column in some circumstances would be to define it as 'not null with default' in the DDL.
Grails doesn't appear to support 'NNWD' directly in constraints. I tested an idea that seems to work as an equivalent:
String name = default
...
name nullable:false
I wondered if dbm-gorm-diff changleog-n.xml would be able to detect this as being a null with a default. But it didn't. That's with version 1.2.2. I see that Liquibase supports this via its <addNotNullConstraint.
Are there any plans to introduce this support? Any suggestions as to how I might work round this, perhaps via a user-written script that makes use of dbm scripts.
Problem:
I tried using 1.3.2, but I get a MissingMethodException when running the script. The actual error line is:
groovy.lang.MissingMethodException: No signature of method: static grails.plugin.databasemigration.ScriptUtils.executeAndWrite() is applicable for argument types: (java.lang.String, java.lang.Boolean, DbmGormDiff$_run_closure1_closure2) values: [changelog-with-data.xml, false, DbmGormDiff$_run_closure1_closure2#2f673724]
Which I don't understand since the args seem to match the signature of the executeAndWrite() method in the plugin's code.
Regards, John
I have done some investigation on this topic and realised that the solution is more complicated, and trying to solve by adding a column using 'not null with default' is not the way to go. As I am planning to use Liquibase and Ant to update the database in test, uat and live environments, I refer to using xml files below.
If the table doesn't have any data, then you can add a column that is 'not null'. This seems to me to be an unlikely situation for a live database.
When the table contains data a new column must be defined as null. There is 3-step process, which requires manual updates to the xml file generated by the plugin:
define the new domain attribute as 'nullable:true', and generate the diff xml file.
update the xml file to add a new changeset using the < SQL> tag:
< sql>update [table] set [column]='dflt value' where [column] is null< /sql>
Now you can define the new column as not-null. Could use more raw sql, or look up Liquibase's < addNotNullConstraint>.
I don't think there is really a need for a default value for the column, since Grails will ensure that nulls don't get through from the browser. I say this since I haven't found a way to alter the definition of the added column so it has a default value.
John
If you're using 1.4.0 version of plugin it doesn't generate the changelog xmls for default values but you can edit the generated files to add the defaultValue & value attributes where it'll add the non-null columns without errors by updating the existing records with the value attribute.
Here's a small example for what it'd look like after modification:
<changeSet author="anybody (generated)" id="1467324956xxx-xx">
<addColumn tableName="table1">
<column name="col1" type="varchar(10)" defaultValue="value1" value="value1">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
More info you can find on liquibase docs http://www.liquibase.org/documentation/column.html
http://www.liquibase.org/documentation/changes/add_column.html

Removing commas from Grails' Scaffolds for Longs

I'm completely new to grails and I'm trying to deploy some simple applications using grails' scaffolding. I have a field in a domain class that stores barcodes as Longs. The default display in Grails' scaffolding is to display these Longs with commas separating every third numeral (e.g. 1,234,567). My searching of the documentation is getting me nowhere, is there a way of easily turning off this formatting until I can get a proper layout set up.
Thanks.
After generation of the scaffolded controllers and gsp files you could use the gsp tag g:formatNumber (see http://www.grails.org/GSP+Tag+-+formatNumber?xhr=true).
Maybe you can also customise the templates used for generation see docs for "grails install-templates" (http://www.grails.org/Artifact+and+Scaffolding+Templates) and get it working for dynamic scaffolding also... ymmv.
('tis my first post, be gentle)

How do you use a String array as a member field in a Grails domain?

I'm trying to create a basic grails domain object and for one of the fields I want to use an array of Strings. However even after running grails generate-views I still don't see the ability to edit said array. Am I going about this wrong?
If you run 'grails install-templates' you can edit src/templates/scaffolding/renderEditor.template which is where the HTML generation for editors is defined. Add in a new "else if" for String[]:
else if (property.type == String[].class)
out << renderStringArrayEditor(domainClass, property)
and implement renderStringArrayEditor however you think best:
private renderStringArrayEditor(domainClass, property) {
...
}
I have no idea what HTML to use, but I might go with a textarea and split on \n. Whatever you decide on, you'll need to convert the input parameter to a String array in your controller methods.
If you're already run 'grails generate-all' or 'grails generate-views' you'll need to run 'grails generate-views' to regenerate your GSPs with the new editor.

Resources