update unidirectional one to one problem - grails

I have two domain classes:
class Domain1 {
String val11
String val12
Domain2 domain2
static constraints = {
}
}
class Domain1Controller{
/**
* Create new Domain1 entity instance
*/
def create = {
def domain1 = new Domain1()
def domain2 = Domain2.get(params.domain2)
if(domain2!=null){
domain1.domain2 = domain2
}
domain1.properties=params
domain1.save(flush: true)
String strJson = (domain1 as JSON)
render strJson
}
/**
* Update Domain1 entity fields values
*/
def update = {
Domain1 domain1 = Domain1.findById(params.id)
params.remove("id")
if (domain1 != null) {
domain1.properties=params
domain1.save(flush:true)
String strJson = (domain1 as JSON)
render strJson
}
}
}
class Domain2 {
String val21
String val22
static constraints = {
}
}
class Domain2Controller{
/**
* Create new Domain2 entity instance
*/
def create = {
def domain2 = new Domain2()
domain2.properties=params
domain2.save(flush:true)
String strJson = (domain2 as JSON)
render strJson
}
/**
* Update Domain2 entity fields values
*/
def update = {
Domain2 domain2 = Domain2.findById(params.id)
params.remove("id")
if (domain2 != null) {
domain2.properties=params
domain2.save(flush: true)
String strJson = (domain2 as JSON)
render strJson
}
}
}
My problem is when I create associated objects,I cannot update domain1.
I think reason maybe in save() method... maybe not
Is there anyone who know why I cannot update Domain1 properties ?
I use grails-1.3.2 and hbase-0.2.4 plugin.
P.S. hbase does not understand mapping..
Thanks for help.

Given the exception you provided in the comment, I think the problem is the line where You call domain1.properties=params. Domain properties map contain some specific keys, and when you assign params map to it, those specific (ie. class property here) are missing, so GORM cant access them.
Use bind() method to bind parameter values to your domain object this way:
def domain1 = new Domain1()
bind(domain1, params)
def domain2 = Domain2.get(params.domain2)
if(domain2!=null){
domain1.domain2 = domain2
}
domain1.save(flush: true)

Related

how validate data that is not send by Post method?

i have a static object in controller that will be fill in some level of registration forms.finally i want to validate this object by modelstate method but is not possible because that is not send by post method..i am searching a standard way to validate..
public class AccountController : Controller
{
private MyDb db = new MyDb();
private static Trainer trainer = new Trainer();
public Trainer InfoSave(Trainer info)
{
trainer.SchoolGrade = info.SchoolGrade;
trainer.SchoolMajor = info.SchoolMajor;
trainer.MajorId = info.Major.Id;
trainer.History = info.History;
trainer.Major = info.Major;
if (ModelState.IsValid)
return true;
else
return false;
}
You can use some Third party library for loosely couple the validation logic. I am using FluentValidation library. You can utilize it:
using FluentValidation;
public class TrainerValidator : AbstractValidator<Trainer> {
public TrainerValidator() {
RuleFor(c=> c.Name).NotNull().WithMessage("Name is required");
}
}
public class AccountController : Controller
{
private MyDb db = new MyDb();
private static Trainer trainer = new Trainer();
public Trainer InfoSave(Trainer info)
{
trainer.SchoolGrade = info.SchoolGrade;
trainer.SchoolMajor = info.SchoolMajor;
trainer.MajorId = info.Major.Id;
trainer.History = info.History;
trainer.Major = info.Major;
TrainerValidator validator = new TrainerValidator();
ValidationResult result = validator.Validate(trainer);
if (result.IsValid)
return true;
else
return false;
}
You can extend it based on your requirements. Here is the link for the same FluentValidation

Grails search from one to many is not working

Here are my domain class,
class Company {
String name
static hasMany = [groups:CompanyGroup]
}
class CompanyGroup{
String name
static belongsTo = [company:Company]
}
I receive params that contain name of CompanyGroup and I want to get the result of company that have the CompanyGroup found.
I did like this,
def groupList = account.companies.groups.flatten()
def groupResult = groupList.findAll{
it.name ==~ /(?i).*${params.keyword}.*/
}
I got the Companygroups that have name from params.key from above code. So I want to render company list that have these group like this,
def com = Company.withCriteria{
eq("groups", groupList)
}
render [companies : com]
It doesn't work!
def com = Company.withCriteria{
inList("groups", groupList)
}

Field values rendered null when using HTTP GET call in grails

This is domain class of Person :
package com.sample
class Person {
String id
String name
Integer age
Address address
static hasMany = [pets:Pet, alias: String, aliases : Alias]
static mapWith = "mongo"
static constraints = {
address nullable:true
pets nullable :true
}
}
This is the domain class of Address :
package com.sample
class Address {
String address
static mapWith = "mongo"
static constraints = {
address maxSize: 1000
}
}
This is ShowPerson method in PersonController:
def showPerson(String name,String age){
if(Person.findByAgeAndName(age,name) != null) {
render Person.findByAgeAndName(age,name) as JSON
}
else {
def addobj = new Address(address: "kondapur")
addobj.save(flush:true)
def pet1 = new Pet(name : "Dog", breed : "A")
pet1.save(flush:true)
def alias1 = "ALIAS1"
def alias2 = "ALIAS2"
def list = ["A"]
def aliases1 = new Alias(aliasname : [list])
aliases1.save(flush:true)
def person = new Person(name : name, age : age, address : addobj, pets : [pet1], alias : [alias1, alias2], aliases : [aliases1])
person.save()
render person as JSON
}
}
Initially there are no persons in DB(which impliesPerson.findByAgeAndName(age,name) == null) Hence it creates a new object and saves it in database). So when I click on the url
> http://localhost:8080/TestJson/showPerson/sample/23
The output now is :
Now when I reclick on the same url (implies Person.findByAgeAndName(age,name) != null) Hence it gets from the database):
The output now is :
In database the address is saved as :
In database the person is saved as :
Can someone tell me how can I get the address (encircled in red) as not null and get the corresponding value when I try to get a saved object from database (i.e in this case kondapur and not null)
Grails JSON marshaller by default doesn't add nested classes, you have to add one line of code:
def showPerson(String name,String age){
JSON.use('deep')// <============================== Add this line
if(Person.findByAgeAndName(age,name) != null) {
render Person.findByAgeAndName(age,name) as JSON
}
else {
def addobj = new Address(address: "kondapur")
addobj.save(flush:true)
def pet1 = new Pet(name : "Dog", breed : "A")
pet1.save(flush:true)
def alias1 = "ALIAS1"
def alias2 = "ALIAS2"
def list = ["A"]
def aliases1 = new Alias(aliasname : [list])
aliases1.save(flush:true)
def person = new Person(name : name, age : age, address : addobj, pets : [pet1], alias : [alias1, alias2], aliases : [aliases1])
person.save()
render person as JSON
}
}

Saving related entity in grails

I have a problem with saving form values from two domain classes
One class is
class Ip {
String inetAddress
String dns
String os
String toString(){
"${inetAddress}"
}
Hoster hoster
static constraints = {
....
and the second one is just
class Hoster {
static HOSTER_OPTIONS = ["Name1", "Name2", "Name3"]
String name;
String toString(){
"${name}"
}
List ips = new ArrayList()
static hasMany = [ips : Ip]
static constraints = {
name(unique: true, blank: false, inList: HOSTER_OPTIONS)
}
I have a Controller where I handle the data from a form
def systems = new Ip()
systems.inetAddress = params.ip
systems.dns = params.dns
systems.os = params.os
systems.hoster.name = params.hoster
def result = systems.save(flush: true, failOnError: true)
But I didn't get it managed that the data is saved.
You're not associating correctly your domain classes in the controller:
systems.hoster.name = params.hoster
Instead of setting the name, you need to set the instance that exists in the database:
systems.hoster = Hoster.findByName(params.hoster)

Grails , How to accessing current ?lang in domain class

http://localhost:8080/app/?lang=EN
-----------------------------------------------
Domain
class Company {
String nameJp
String nameEn
static constraints = {
}
String toString(){
if(lang=='EN')
return nameEn ? nameEn:nameJp
else
return nameJp
}
}
How can i check current languages in domain class
You can try LocaleContextHolder or pass the current Locale as param:
String toString() {
return toString(LocaleContextHolder.getLocale())
}
//get the possibility of passing a Locale (better also for tests)
String toString(Locale locale) {
if(locale.language == 'en') {
return nameEn ? nameEn:nameJp
} else {
return nameJp
}
}
But this is more a presentation need than a Domain Class need, so you can create a TagLib and handle this there.
class CompanyTagLib {
static namespace = "comp"
def name = { attrs ->
Locale locale = attrs.locale ? attrs.remove('locale') : ResquestContextUtil.getLocale(request)
Company company = attrs.remove('company')
...
}
}
Not sure that you can access it in domain class, but in controller you can get it from session
session[SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME]

Resources