I have a domain class called Application as follows:
class Application {
static hasOne = [resumption:Resumption, employee:Employee]
//Employee employee
Date startDate
Date endDate
Integer amountOfDays
String leaveRecommended
String leaveNotRecommended
Date supervisorDate
String toString(){
return "Application for ${employee.lastName}, ${employee.firstName}"
}
}
In the ApplicationController I'm trying to write a query that is going to find all applications that match a particular employee id. I do so as follows:
def applicationlist(){
if(!params.max){
params.max = 10
}
def query
def criteria = Application.createCriteria()
def results
query = { eq("employee_id", Long.parseLong("1")) }
results = criteria.list(params, query)
render(view:"employeeapplicationlist", model:[applicationlist:results])
}
Now I keep getting the error: "could not resolve property: employee_id"
I've checked the generated Application table in MySql, there is a column called employee_id with a value. The weird thing is I can access any other property (like amountOfDays), so what's the deal with employee_id? Why is it complaining that it cannot resolve the property? What am I missing? Thanks in advance.
Associations in the criteria DSL are of the form
Application.withCriteria{
employee{
eq 'id', 1
}
}
http://grails.org/doc/latest/guide/GORM.html#criteria
But you could probably just do:
def employee = Employee.proxy(1)
Application.findAllByEmployee( employee )
This appears a few times in the Grails User Guide as 'querying associations'
Oh well it looks like I'm still not fully adjusted to interfacing with the database on an Object level. For anyone else with this or a similar problem, here's the fix:
query = { eq("employee.id", Long.parseLong("1")) }
Sine the Application Domain class has one Employee, then we just need to access the id field of that employee. Remember we're in the ApplicationController.
Related
I have an array of Persons (class contain name and lastname and id )
what I have to do is to return a string form this array but in a specific format an example will be more explicative
array=[PERS1,PERS2]
I need this as a return value : "The name of all persons : "+ PERS1.name + PERS1.LASTN + " , " + PERS2.name +PERS2.LASTN +","
I know this method
array.each{ |per|
#but this will not return the format ,and with each I think I can only print (I'm new in the ruby field
}
all of this because I need it when overriding to_s , because I need to provide a string -> to_s
def to_s
"THE name of all preson"+#array.each #will not work as I want
end
Thank you for ur time and effort and if you need any clarification please let me know
each just iterates over a collection and returns the collection itself. You may want to use map and join the result.
array.map { |person| "#{person.name} #{person.lastn}" }.join(',')
Or if you modify your Person class it can be even simpler.
# I assume that the name of the class is Person and name and lastn are always present
class Person
def full_name
"#{person.name} #{person.lastname}"
end
end
# Then you can call this method on `map`.
array.map(&:full_name).join(',')
Try this,
array.each do |per|
"#{per.name} #{per.LASTN}"
end
For more info check Interpolation
I have two methods that are identical apart from the ActiveRecord class they are referencing:
def category_id_find(category_name)
category = Category.find_by_name(category_name)
if category != nil
return category.id
else
return nil
end
end
def brand_id_find(brand)
brand = Brand.find_by_name(brand)
if brand != nil
return brand.id
else
return nil
end
end
Now, I just know there must be a more Railsy/Ruby way to combine this into some kind of dynamically-created method that takes two arguments, the class and the string to find, so I tried (and failed) with something like this:
def id_find(class, to_find)
thing = (class.capitalize).find_by_name(to_find)
if thing.id != nil
return thing.id
else
return nil
end
end
which means I could call id_find(category, "Sports")
I am having to populate tables during seeding from a single, monster CSV file which contains all the data. So, for example, I am having to grab all the distinct categories from the CSV, punt them in a Category table then then assign each item's category_id based on the id from the just-populated category table, if that makes sense...
class is a reserved keyword in Ruby (it's used for class declarations only), so you can't use it to name your method parameter. Developers often change it to klass, which preserves the original meaning without colliding with this restriction. However, in this case, you'll probably be passing in the name of a class as a string, so I would call it class_name.
Rails' ActiveSupport has a number of built in inflection methods that you can use to turn a string into a constant. Depending on what your CSV data looks like, you might end up with something like this:
def id_find(class_name, to_find)
thing = (class_name.camelize.constantize).find_by_name(to_find)
...
end
If using a string, you can use constantize instead of capitalize and your code should work (in theory):
thing = passed_in_class.constantize.find_by_name(to_find)
But you can also pass the actual class itself to the method, no reason not to:
thing = passed_in_class.find_by_name(to_find)
I'm doing integration tests for controllers in grails.I need to pass query string in test case and I'm passing it as controller.request.queryString for the same.
My tests is getting failed. It's giving me null value for the query String parameter.
Controller - UserExController
Foll is the action on which i'm doing integration testing.In this I'm reading query string parameter 'uid' and getting the userInstance using GORM method
def getUser() {
//reading the query string parameter 'uid'
def userId = request.getParameter("uid")
User user = User.findByUsername(userId)
render view:'edit', model:[userInstance:user]
}
This is the test for the above written action .In this I'm passing the query string parameter and calling the action
class UserInstanceTests extends GroovyTestCase {
#Test
void testPerfSummaryApi() {
def userExController=new UserExController()
userExController.request.queryString='uid=rp123'
userExController.getUser()
def model = userExController.modelAndView.model.userInstance
assertNotNull model
}
}
I'm getting groovy.lang.MissingMethod.Exception in the foll call:
User.findByUsername(userId) //userId is comming null
Change in Controller:
def userId = request.getParameter("uid")
to
def userId = params.uid
Change in int test:
userExController.request.queryString='uid=rp123'
to
userExController.params.uid='rp123'
Grails' dynamic binding helps in binding the query parameters to params and request to request in the controller.
This should make things work for you (tested on Grails 2.0.4):
userExController.request.addParameter('uid', 'rp123')
However, I would recommend to turn to dmahapatro's suggestion and refactor your controller to use params.uid instead of request.getParameter("uid"). Or even introduce a command object. The way you are doing it now just does not seem to be the standard Grails way.
I am working on a project and I have two domains.
class Author {
Book book
String name
}
class Book {
Author author
String title
}
I have saved an instance of domain Author in database and in a service I do something like this:
def authorInstance = Author.getById(1)
def bookInstance = new Book(author:authorInstance, title: "Foo")
But i do not save the bookInstance rather, I use it for couple of more processes. This gives me org.hibernate.TransientObjectException. I also tried to do something like:
def authorInstance = Author.getById(1)
def aI = authorInstance
def bookInstance = new Book(aI, title: "Foo")
But in this case too, I get the same error. I am working in this way because I am working in legacy code, so I cannot change much. Is there a work around for this ?
You're apparently changeing some field of authorInstance you set. That's what TransientObjectException says: "object references an unsaved transient instance". Please do read and do quote the error messages.
Save the Author before saving a book. Or do not modify it.
An you probably would like to use hasMany and belongsTo.
By the way, there is another issue with your possible replacement code. Instead of:
def bookInstance = new Book(aI, title: "Foo")
you would need
def bookInstance = new Book(author:aI, title: "Foo")
Book has an in-memory constructor declared which takes a Map object and "author" and "title" are keys into that Map. This constructure then uses the map to initialize class members.
I'm trying to do something like:
if filter_1
#field = #field.where()
else
#field = #field.where()
end
if filter_2
#field = #field.order()
end
etc.
But how do I init #field with an empty query? I tried #field = Field.all but that gives an array so not allowing chaining.
Try scopedon Model class e.g.
#fields = Field.scoped
#fields = #fields.where("your conditions") if filter_1
#fields = #fiels.order("your conditions") if filter_2
The first time you are initializing the #field instance variable, Please try referring to the class Field, i.e.
Filter1: #field = Field.where(...)
Afterwards if you need to keep adding further filters you can refer to your variable field as many times as you want to.
Filter2 onward: #field = #field.where(...)
As Filter1 would return an active Record relation, you can nest more condition clauses onto it. Also do not worry about performance issues as the SQL will only be generated and processed once it is actually needed.(lazy loading)
If you to #field.to_sql at the end of your filters, you'll be able to see that all of your where clauses have conveniently been nested together into one SQL statement.
Also, I'd recommend you to read Active Record Query Interface
EDIT
Create a method get_field. And use that to add filter results.
def get_field(field)
#field.is_a?(ActiveRecord::Relation) ? Field : field
end
get_field(#field).where(....)
get_field(#field).where(....)