How to get params in a model? - grails

How to get params in a model (in Grails) ? params. does not exist in a model.

If by "Model" you mean a Domain Model class, they don't have params, they're just POJOs. Params only apply to Controllers, as far as I know.

IF your parameter names are propertly formated and match the domain attributes, you can do this:
Assuming
params = [name:"some name", age: "194", civilState: "MARRIED"]
and
class Person{
String name
Integer age
CivilStatus civilState //some enum
}
You can leverage groovy's property binding constructor like this in a controller:
class Controller {
def saveAction = {
new Person(params)
}
}

As I understand you have a special method for filling domain from request. At this case you could pass all params (it's a Map) to such method, like:
def MyDomain {
static MyDomain buildFromParams(def params) {
return new MyDomain(
field1: params.field_1, //assuming that your params have different naming scheme so you can't use standard way suggested by Raphael
field2: params.field_2
)
}
}
class MyController {
def myAction() {
MyDomain foo = MyDomain.buildFromParams(params)
}
}

Related

Using certain parts of URL as params in a Grails Controller

I've created a static URL in Grails:
class UrlMappings {
static mappings = {
...
"/remittance/bank"{
controller={"BankRemittance"}
action=[GET:"index"]
}
"/remittance/bank/$bankId/spd/$spdId"{
controller={"SPD"}
action=[GET:"show"]
}
...
}
}
Now what I want is to retrieve bankId and spdId values of the URL on my SPDController:
class SPDController {
def myService
def show() {
String bankId = ? // code to get bankId from the URL
String spdId = ? // code to get spdId from the URL
render(
view: "...",
model: myService.transact(bankId, spdId)
)
}
}
But how can I do that? It seems using params.bankId and params.spdId is not for this scenario.
Your action should accept the URL parameters as arguments.
def show(String bankId...)

How can I pass data between GSP and controller in Grails without storing in the database?

Is it possible to enter data in the GSP view and use this data in the controller inside the program to do some operations without storing this data in the domain. For example I have a g:textField and I enter my name. I want to be able to use the name that I enter in the controller to manipulate.
None of the data passed from a view to a controller has to line up with any particular Domain. There are a couple of ways you could do this.
the view:
<g:textField name="name" />
the controller:
class SomeController {
def someAction() {
def name = params.name
// do something with name
}
}
You could also use a Command Object.
the command object:
#Validateable
class SomeCommand {
String name
static constraints = {
name nullable: false
}
}
the controller:
class SomeController {
def someAction(SomeCommand someCommand) {
if (!someCommand.hasErrors()) {
def name = someCommand.name
// do something with name
}
}
}

Grails Reusable Service for saving Domain Objects

I have a Grails project with multiple Domain Classes, and I want to make a persistence service as reusable as possible by only having one save() inside of it. To try and achieve this I have done the following in my project.
//PersistenceService.groovy
#Transactional
class PersistenceService {
def create(Object object) {
object.save flush: true
object
}
//BaseRestfulController
class BaseRestfulController extends RestfulController {
def persistenceService
def save(Object object) {
persistenceService.create(object)
}
//BookController
class BookController extends BaseRestfulController {
private static final log = LogFactory.getLog(this)
static responseFormats = ['json', 'xml']
BookController() {
super(Book)
}
#Transactional
def save(Book book) {
log.debug("creating book")
super.save(book)
}
So basically I have a bunch of domains for example Author etc, each with their own controller similar to the bookController. So is there a way to reuse the service for persistence like I am trying above?
Thank you
I'm doing something similar, but mainly because all my entities are not actually removed from the database but rather "marked" as removed. For several apps you need such an approach since it's critical to prevent any kind of data loss.
Since most databases do not provide support for this scenario, you can't rely on foreign keys to remove dependent domain instances when removing a parent one.
So I have a base service class called GenericDomainService which has methods to save, delete (mark), undelete (unmark).
This service provides a basic implementation which can be applied to any domain.
class GenericDomainService {
def save( instance ) {
if( !instance || instance.hasErrors() || !instance.save( flush: true ) ) {
instance.errors.allErrors.each {
if( it instanceof org.springframework.validation.FieldError ) {
log.error "${it.objectName}.${it.field}: ${it.code} (${it.rejectedValue})"
}
else {
log.error it
}
}
return null
}
else {
return instance
}
}
def delete( instance, date = new Date() ) {
instance.dateDisabled = date
instance.save( validate: false, flush: true )
return null
}
def undelete( instance ) {
instance.dateDisabled = null
instance.save( validate: false, flush: true )
return null
}
}
Then, in my controller template I always declare two services: the generic plus the concrete (which may not exist):
def ${domainClass.propertyName}Service
def genericDomainService
Which would translate for a domain called Book into:
def bookService
def genericDomainService
Within the controller methods I use the service like:
def service = bookService ?: genericDomainService
service.save( instance )
Finally, the service for a given domain will inherit from this one providing (if needed) the custom logic for these actions:
class BookService extends GenericDomainService {
def delete( instance, date = new Date() ) {
BookReview.executeUpdate( "update BookReview b set b.dateDisabled = :date where b.book.id = :bookId and b.dateDisabled is null", [ date: date, bookId: instance.id ] )
super.delete( instance, date )
}
def undelete( instance ) {
BookReview.executeUpdate( "update BookReview b set b.dateDisabled = null where b.dateDisabled = :date and b.book.id = :bookId", [ date: instance.dateDisabled, bookId: instance.id ] )
super.undelete( instance )
}
}
Hope that helps.

Grails createCriteria on abstract domain

I am quite curious how one would use the criteria builder to access fields of an inherited class.
Let's assume we have the following class:
class A {
String fieldOne
String fieldTwo
static hasMany = [childs: AbstractChildClass]
}
and the abstract child class would look like this:
abstract class AbstractChildClass {
Integer valueOne
Integer valueTwo
A a
static mapping
tablePerHierarchy false
}
}
of course there are several extending classes such as:
class ExtendingClassOne extends AbstractChildClass {
DesiredObject desiredObject
static mapping = {
tablePerHierarchy false
}
}
let's also assume there is the class DesiredObject which looks like this:
class DesiredObject {
String infoA
String infoB
}
The question is how one would get the fields infoA and infoB by creating a criteria for class A. My approach so far is this:
A.createCriteria().list {
childs {
desiredObject {
ilike('infoA', '%something%')
}
}
}
This of course does not work because in the table ExtendingClassOne is only the id of the desiredObject and I have no clue how to join the object with the criteria builder to get its fields.
Thank you for reading.
Marco
don't expect 100% match between your domain model and the DB schema it's related to.
In your case the polymorphism would work only with tablePerHierarchy true for AbstractChildClass.
If you do want to stick with tablePerHierarchy false, you can define your class like:
class A {
static hasMany = [ childrenOne:ExtendingClassOne, childrenTwo:ExtendingClassTwo ]
}
thus your query would be as simple as:
A.withCriteria{
for( String c in [ 'childrenOne', 'childrenTwo' ] ){
"$c"{
desiredObject {
ilike('infoA', '%something%')
}
}
}
}

Partial view action send parameter

How do I send array parameters to the action method?
How do I create a array variable?
partialView.page
I tried that but it did not work.
#{ Html.RenderAction("GetDefinationType", "Crew", new { category = "Competency","crew",Person" }); }
Thank you
you can do like this in View:
#{
var temp = new[] { "Competency", "crew", "Person" };
}
#Html.Action("GetDefinationType", "Crew",new{category =temp })
Action:
public ActionResult GetDefinationType(string[] category)
{
return Content("");
}
At the method GetDefinationType you have to let it accept a parameter with the name CategoryOptions, this will be the class (parameters) you are passing.
public class CategoryOptions
{
string[] myArray { get; set; }
}
This is how to call and use it:
#{ Html.RenderAction("GetDefinationType", "Crew", new { category = new CategoryOptions { myArray = new string [] {"Competency","crew","Person"}} }); }
The other two answers were almost right, but over-complicated.
If you want to pass an array of strings as a parameter, just pass an anonymously typed array of strings as your named category parameter:
#{Html.RenderAction("GetDefinationType", "Crew", new { category = new [] {"Competency","crew","Person"} });}
Use Html.Action, not HTML.RenderAction
Note: RenderAction is for use in code blocks (as you have added), but you can just use the simpler #Html.Action for inline Razor code:
#Html.Action("GetDefinationType", "Crew", new { category = new [] {"Competency","crew","Person"} })
In either case the controller action method just needs to accept a parameter called category of type string[].
e.g.
public ActionRresult GetDefinationType(string[] category)
{
// do something with the list of categories
}
Also, unless you mean the slang combination of defamation and definition, "defanation" please spell it definition :)

Resources