Grails where query criteria qualification - grails

Is there a way to qualify method parameters versus domain properties in a Grails where query criteria when they are named identically?
For example:
def getPeople(age, sex) {
People.find { age == age && sex == sex }
}

Something like this!?
def getPeople(age, sex) {
People.find { delegate.age == age && delegate.sex == sex }
}

Related

System.NotSupportedException in Entity Framework (ASP.NET MVC)

I have an ASP.NET MVC5 project with Entity Framework. I have people (Pajtas class) which are in groups (every group has a unique number). The users can edit the people's information but only if the user has permission to the group in which the person is.
Every user has an IfiAdatlap object and the IfiAdatlap object has the permissions for the numbered groups. So I have a simple permisison class:
public class CsoportHozzaferes
{
[Required]
[Key]
[Column(Order = 1)]
public int Csoport { get; set; }
[Required]
[Key]
[Column(Order = 2)]
public virtual IfiAdatlap IfiAdatlap { get; set; }
}
In my controller I have a function to check that the current user's IfiAdatlap object has permission to the group in which the person is whose information the user would like to edit. First of all I get the current user's ApplicationUser object (user), than I try to get the list of groups (csoportok) for which the user has permission to be able to check that the person's group number (pajtas.Csoport) is in this list or not.
private void PajtasHozzaferesCheck(Pajtas pajtas)
{
var userName = User.Identity.Name;
var user = db.Users.FirstOrDefault(x => x.UserName == userName);
var csoportok = db.CsoportHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(csh => csh.Csoport).ToList();
if (!(pajtas.Csoport != null && csoportok.Contains((int)pajtas.Csoport)))
{
var tanfolyamok = db.TanfolyamHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(tfh => tfh.Tanfolyam).ToList();
var tfosztalyok = db.TanfolyamHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(tfh => tfh.Osztaly).ToList();
if (!(pajtas.TanfolyamOsztaly != null && pajtas.TanfolyamSorszam != null && tanfolyamok.Contains((int)pajtas.TanfolyamSorszam) && tfosztalyok.Contains((TanfolyamOsztaly)pajtas.TanfolyamOsztaly) && tanfolyamok.IndexOf((int)pajtas.TanfolyamSorszam) == tfosztalyok.IndexOf((TanfolyamOsztaly)pajtas.TanfolyamOsztaly)))
{
var tanfvez = db.TanfolyamvezetesHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(tfvh => tfvh.Tanfolyam).ToList();
if (!(pajtas.TanfolyamSorszam != null && tanfvez.Contains((int)pajtas.TanfolyamSorszam)))
{
if (!(User.IsInRole("Nevelo") || User.IsInRole("Admin")))
{
//nincs jogosultság
throw new HttpException((int)System.Net.HttpStatusCode.Forbidden, "Hozzáférés megtagadva");
}
}
}
}
}
But I get an exception at line var csoportok = ...:
System.NotSupportedException: 'Unable to create a constant value of type 'Ifi.Models.Adatlap'. Only primitive types or enumeration types are supported in this context.'
Thanks for any help!
I presume Adaplap is an entity.Change where condition using id instead comparing instances,eg:
.Where(h => h.IfiAdatlap != null && h.IfiAdatlap.Id == user.Adatlap.Id)
The problem is h.IfiAdatlap == user.Adatlap. Because this is a complex type, it won't be accepted, as EF does not know how to do the comparison. You need to compare the ids, something like h.IfiAdatlap.Id == user.Adatlap.Id.

Deep object validation

I have 3 classes
class Company {
String company_name
}
class Job {
String job_name
Company company
}
class Person {
String person_name
Job job
}
How can I check if a position is really existing from an existing company and it is vacant (no Person is on it) or in other words there is existing Job object with existing Company of course but no Person has in his constructor passed this Job object, here is what I have done,where is my mistake ?
if (person==null && job != null && company != null)
{
def query=Job.where{company.company_name == company_name && job_name == job_name}
def query2=Person.where {job.job_name == job_name}
if( query == null && query2 != null )
{
def person12 = new Person(job: job, person_name: person_name)
if (person12.validate() && person12.save())
{
redirect(url: "https//localhost:8080")
}
}
I would relate the classes in other way if possible:
class Company {
String company_name
static hasMany = [jobs: Job]
}
class Job {
static belongsTo = [company: Company]
static hasOne = [person: Person]
String job_name
}
class Person {
String person_name
static belongsTo = [job: Job]
}
And then you can create a criteria to know if a job has no person related.
List<Job> jobs = Job.withCriteria{
eq('company', companyObject)
isNull('person')
}
You don't need to validate an object before save it, cause it automatly validated before, and if it is not valid, return false.
if (person12.save()) {
redirect(url: "https//localhost:8080")
}

How to handle some null entries when populating entity model from multiple linq

I am populating a viewmodel from two queries:
Model:
Student (Name, teacher, HomeroomName, HomeRoomLocation)
The two queries are for the student table, and the Homeroom table. It is possible and ok for the student to not have a homeroom assigned.
var student = context.Student.where(c => c.stuid == studentId).SingleOrDefault();
var homeroom = context.HomeRoom.where(c => c.stuid == studentId).SingleOrDefault();
if(student != null)
{
Student student = new Student
{
Name = student.Name,
Teacher = student.Teacher.Name,
HomeRoomName = homeroom.Name,
HomeRoomLocation = homeroom.Location
};
}
If the homeroom query is null, which is totally fine per the business rules, everything blows up. I could have a bunch of if conditions and return a single model, but I would rather do it in one shot.
Can I do inline ?? in the model population? Like
HomeRoom = homeroom.Name == null ? null : homeroom.Name,
What you need to check is if homeroom variable is null or not:
HomeRoom = homeroom == null ? null : homeroom.Name,
In C# 6.0 you can use Null-Conditional Operator:
HomeRoom = homeroom?.Name,
The null-conditional operator checks whether the operand (in this case homeroom variable) is null prior to invoking the Name property.The logically equivalent explicit code would be the following:
(homeroom!= null) ? homeroom.Name : null
This will allow you to check both variables for null, and create your object, or create a student with no homeroom if the homeroom is null.
if (student != null & homeRoom != null) {
Student student = new Student {
Name = student.Name,
Teacher = student.Teacher.Name,
HomeRoomName = homeroom.Name,
HomeRoomLocation = homeroom.Location
};
} else if (student != null) {
Student student = new Student {
Name = student.Name,
Teacher = student.Teacher.Name
};
}
Why you don't create a constructor inside your Student class?
public Student() {
}
public Student(Student student, HomeRoom homeroom) {
this.Name = student.Name;
this.Teacher = student.Teacher.Name;
if(homeroom != null) {
this.HomeRoomName = homeroom.Name;
this.HomeRoomLocation = homeroom.Location;
}
}
So you can use like this:
var newStudent = new Student(student, homeroom);

Grails Gorm Query Restriction

I have two domains
class ProductQuantity {
Integer quantity
static belongsTo = [productSize: ProductSize]
}
class ProductSize {
String size
static hasMany = [productQuantities : ProductQuantity]
}
I'm trying to build a query where I get all ProductQuantity by the productSize. I have the following query that works.
def productSize = ProductSize.findAllById(1);
def productQuantities = ProductQuantity.findAllByProductSize(productSize)
I'm looking to get the ProductQuanties in a single query rather than two separate queries.
ProductQuantity.createCriteria().list {
eq 'productSize', ProductSize.load(1)
}
or
ProductQuantity.withCriteria {
eq 'productSize', ProductSize.load(1)
}
or
ProductQuantity.where {
productSize == ProductSize.load(1)
}.list()
or
ProductQuantity.findAll("from ProductQuantity where productSize = ?", [ProductSize.load(1)])
Yes, you can get this by createCriteria, like --
def productQuantities = ProductQuantity.createCriteria().list() {
productSize {
eq('id', 1)
}
}

Grails GORM: list all with nested property

My (simplified) domain model looks like this:
class Student {
static hasMany = [professions:StudentProfession];
}
class StudentProfession {
static belongsTo = [student:Student];
Profession profession;
}
class Profession {
String name;
}
What is the most efficient way to:
List all students that are taught "Programmer" and "Manager" professions
Am I forced to filter them out after querying the database?
students = students.findAll { student ->
student.professions.find { professionNames.contains(it.profession.name) } != null
}
You can do this using a GORM query:
def studends = Student.where {
professions {
profession.name == "Programmer" || profession.name == "Manager"
}
}
Lots of ways to skin this cat - here's one:
StudentProfession.findAllByProfessionInList(Profession.findAllByNameInList(["Programmer","Manager"])*.student.unique()

Resources