saving to grails using a specific id/email - grails

I have two domains, Patient and Allergy. I want to save allergies particular to the specific patient(email is the unique identifier for each patient). The details are coming from an android app and email is one of the parameters.
Assuming a user already exists, how would I go about the allergy service to be able to do this.
This is the patient service which successfully registers a new patient and saves their details. I have a controller which acts as an API for the android app.
#Transactional
class PatientService {
//creating new
def updateSave(params) {
def patient
//record exists
if(params.id){
patient = Patient.findById(params.id)
if(patient) {
patient.validate()
patient.dateUpdated = new Date()
patient.save(params)
}
}else{
params.password=MD5CodecExtensionMethods.encodeAsMD5(params.password)
patient = new Patient(params)
patient.validate()
System.out.println(patient.errors)
patient.save flush:true
}
return patient
Here is what I have tried with allergy service but am stuck
#Transactional
class AllergyService {
def Save(params) {
def allergy
Patient patient
allergy = new Allergy(params)
allergy.validate()
System.out.println(allergy.errors)
allergy.save flush:true
return Allergy.findAllByPatient(params)
}

I am assuming that the Patient has many Allergies, so you have to create an appropriate association:
class Patient {
static hasMany = [allergies: Allergy]
}
class Allergy {
}
Grails will automatically inject a Set of allergies into the Patient domain.
In your save method, you should have access to Patient or his email property in order to connect them somehow.
Then, you can do like:
def save(patientEmail, params) {
Patient patient = Patient.findByEmail(patientEmail)
Allergy allergy = new Allergy(params)
patient.addToAllergies(allergy)
patient.save()
}

Related

Grails findBy belongsTo gives JdbcSQLException

Say, for a system, I had Student and User objects, like so:
User {
}
Student {
User user //not nullable
static belongsTo = [User]
}
Teacher {
static belongsTo = [user:User]
}
I have a lot of code written against these models, and plenty of dynamic finders in it
def u1 = new User().save( flush: true)
new Student( user: u1 ).save( flush: true)
...
def s = Student.findByUser( springSecurityService.currentUser)
//s can be null
def t = Teacher.findByUser( springSecurityService.currentUser)
//t can be null
if( s != null)
//do something with 's'
if( t != null)
//do something with 't'
...
And this all worked fine. But I wanted to update my domain model to add cascading access from User to Student. So I did:
User {
Student student //nullable
}
And I would save a user like this:
new User( student: new Student() ).save( flush: true)
But the problem is, when I try to access 's' like I did above.
If the Student.findByUser can find one such student, then it works.
But if it should return null, it gives an error instead.
def s = Student.findByUser( springSecurityService.currentUser)
will result in:
org.h2.jdbc.JdbcSQLException
Parameter #2 is not set; SQL statement:
select this_.id as id18_0_, this_.version as version18_0_, from student this_ where this_.id=? limit ? [90012-173]
I know I can access the student object through the user object like user.student, but I would like to be able to keep the existing code as it is.
I've seen this thread, and it had a similar problem, but no resolution grails email list
Is this a bug? What can I do to get around it? Am I not setting up my domain models properly?
Thanks
As an alternative, you could try something like this using hasOne instead of belongsTo.
class User {
static hasOne = [student:Student, teacher:Teacher]
static constraints = {
student unique:true, nullable: true
teacher unique:true, nullable: true
}
}
class Student {
User user
}
class Teacher {
User user
}
It still cascades and appears to handle null searches fine.

grails gorm how to do a join with a 3 table hierarchy

My web interface has an ajax call to update a photo's caption. A post sends the caption and the publicId of the photo to a service.
The service has
Photo photo = Photo.findByPublicId(params.publicId)
photo.caption = params.caption
photo.save()
However I have read in Burt Beckwith's grails book this is not secure. As-is a hacker could post any publicId to my service and update the
caption of a photo that doesn't not belong to their session. I need some GORM advice on how to write the update query to update only photos belonging
to the current user's session. Due to the number of joins involved I am lost. I am familiar with getting the profile/user:
User user = User.load(springSecurityService.principal.id)
Profile profile = Profile.findByUser(user, [lock:true])
but not the one query that would join everything for the entire update, instead of Profile.findByUser(user, [lock:true]).photoAlbum.getPhotoWherePublicId(publicId) or something that seems it would make 4 different sql calls.
The domain schema I have with the hierarchy in question is :
//user from springsecurity for session/login management
class User {
//no reference to profile
}
class Profile {
PhotoAlbum photoAlbum
User user //reference to user
static constraints = {
photoAlbum(nullable:true)
}
}
class PhotoAlbum {
static hasMany = [photos:Photo]
static belongsTo = [profile:Profile]
}
class Photo {
static belongsTo = PhotoAlbum
String caption
String publicId
}
Maybe with a criteria or namedQuerie this could be done.
Something like this may work:
First make a small change to your Photo class
class Photo {
PhotoAlbum photoAlbum
static belongsTo = [photoAlbum: PhotoAlbum]
String caption
String publicId
}
and try with this criteria
Photo.withCriteria{
eq 'id',params.publicId
photoAlbum {
eq 'profile',profile
}
}

grails findByDomain returns null

A domain Staff has a User.
class Person {
User user
}
class Staff extends Person {
//other properties
}
class User {
String username
String password
}
I know a user logged in, now I want to find the Staff by the same logged in User. No relation is maintained from User's side.
The code I am implementing is :
def createdBy = User.get(springSecurityService.principal.id)
log.info("User id : "+createdBy.id) // it works
def staff = Staff.findByUser(createdBy) //it returns null
Is this not applicable in GORM or I'm missing something?
grails findBy documentation has nothing to tell about findByDomain().
The question is CLOSED as the error was while inserting a Staff with a User which was not heppening in proper way.(poor grails didn't notify me.)
Above code works perfectly.
def createdBy = User.get(springSecurityService.principal.id)
def staff = Staff.findByUser(createdBy)
But, meanwhile implemented another way of finding Staff in criteria way :
def createdBy = User.get(springSecurityService.principal.id)
def staff = staffCriteria.get{
user{
idEq(createdBy.id)
}
}

Save On My Domain Class Object Is Not Working.

I have a User class which has a List field namely pt. This field is not initialized when User register his account. But when user goes this controller action :
def updatePt() {
//performs some action
def user = User.get(springSecurityService.principal.id) //find the user
user.pt = []
//on certain conditions i put values into user.pt like this
user.pt << "E"
//at last I save it
user.save()
}
But using user/show action via scaffolding I found that pt field is not saved on users object. Where I'm making a mistake?
You have to provide a static mapping in the Users domain class so that Grails knows the field must be persisted:
class User {
static hasMany = [pt: String]
}
It's possible because of validation error. Try with
if (!user.save()) {
log.error('User not saved')
user.errors.each {
log.error('User error: $it')
}
}
PS or you can use println instead of log.error

Saving associated domain classes in Grails

I'm struggling to get association right on Grails. Let's say I have two domain classes:
class Engine {
String name
int numberOfCylinders = 4
static constraints = {
name(blank:false, nullable:false)
numberOfCylinders(range:4..8)
}
}
class Car {
int year
String brand
Engine engine = new Engine(name:"Default Engine")
static constraints = {
engine(nullable:false)
brand(blank:false, nullable:false)
year(nullable:false)
}
}
The idea is that users can create cars without creating an engine first, and those cars get a default engine. In the CarController I have:
def save = {
def car = new Car(params)
if(!car.hasErrors() && car.save()){
flash.message = "Car saved"
redirect(action:index)
}else{
render(view:'create', model:[car:car])
}
}
When trying to save, I get a null value exception on the Car.engine field, so obviously the default engine is not created and saved. I tried to manually create the engine:
def save = {
def car = new Car(params)
car.engine = new Engine(name: "Default Engine")
if(!car.hasErrors() && car.save()){
flash.message = "Car saved"
redirect(action:index)
}else{
render(view:'create', model:[car:car])
}
}
Didn't work either. Is Grails not able to save associated classes? How could I implement such feature?
I think you need a belongsTo in your Engine ie
static belongsTo = [car:Car]
Hope this helps.
For what is worth, I finally nailed it.
The exception I got when trying to save a car was
not-null property references a null or
transient value
It was obvious that the engine was null when trying to save, but why? Turns out you have to do:
def car = new Car(params)
car.engine = new Engine(name: "Default Engine")
car.engine.save()
Since engine doesn't belongs to a Car, you don't get cascade save/update/delete which is fine in my case. The solution is to manually save the engine and then save the car.

Resources