Grails , How to accessing current ?lang in domain class - grails

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]

Related

How to get value in my show page in Grails

How to get the value as following codes with my show view page on Grails?
Person.groovy
package com
class Person {
String person
static constraints = {
person blank:false,nullable:true
}
static hasMany=[task:Task]
String toString(){return person}
static mapping={
}
}
Task.groovy
package com.moog
class Task {
String task
static constraints = {
task blank:false,nullable:true,unique:true
}
static belongsTo=[person:Person]
static hasMany=[tag:Tag]
String toString(){return task}
}
Tag.groovy
package com
class Tag {
String tag
static constraints = {
tag blank:false, nullable:true
}
static belongsTo=[task:Task]
String toString(){
return tag
}
}
First of all try a better wording for your collections
static hasMany=[tasks:Task] // in Person.groovy
static hasMany=[tags:Tag] // in Task.groovy
In your person show.gsp try something like
<g:each in=${person.tasks} var="task">
<p>${task}</p>
</g:each>
If you do not use scaffolding and write you own controller methods to create your entities than maybe this helps you further:
def task = new Task(task:"Clean room")
def person = Person.get(1)
person.addToTasks(task)
person.save()

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...)

Grails one to many relationship Error

I have a User domain Class as follows:
package xyz
class User {
String login
String password
String firstName
String lastName
String address
String email
static hasMany = [
websites: AddWebsite
]
static constraints = {
login blank:false, size:5..15,matches:/[\S]+/, unique:true
password blank:false, size:5..15,matches:/[\S]+/
firstName blank:false
lastName blank:false
email email: true
}
}
and another AddWebsite domain class as follows:
package xyz
import xyz.User;
class AddWebsite {
String website
User user
static belongsTo = [user: User]
static constraints = { website url:true }
}
I am working with MongoDB at the backend. I need that every user who logs in can add websites but a user can't add same websites multiple times but same website can be added by different users. Whenever I try to add a website, it shows me "user cannot be null error".
My controller class for AddWebsite is as follows:
package xyz
class AddWebsiteController {
def index() {
}
def addWebsites() {
if(request.method == 'POST') {
def u = new AddWebsite()
u.properties[
'website'
] = params
if(u.website =="" ) {
u.errors.rejectValue("website", "addwebsite.website.empty")
return [addWebsite:u]
}
else if(u.save()) {
render view:'addWebsites', model:[message: "Successfully saved: \""+u.website+"\" Add more websites..."]
//redirect(controller: "AddWebsite", action: "websiteAdded")
}
else {
return [addWebsite:u]
}
}
}
def websiteAdded() {
}
def failed(){
}
}
Also, I am not sure how to test whether this one to many association. Please help.
Figured it out. I made this change in the controller so that the user won't be null anymore:
def addWebsites() {
if(request.method == 'POST') {
def w = new AddWebsite()
w.properties[
'website'
] = params
w.user = session["user"] //modified
if(w.website =="" ) {
w.errors.rejectValue("website", "addwebsite.website.empty")
return [addWebsite:w]
}
else if(w.save()) {
render view:'addWebsites', model:[message: "Successfully saved: \""+w.website+"\" Add more websites..."]
}
else {
return [addWebsite:w]
}
}
}

update unidirectional one to one problem

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)

MVC grid sorting - customise links

I am using the Sort method of the MvcContrib Grid to generate sorting links, e.g.
<%= Html.Grid(Model).AutoGenerateColumns().Sort((GridSortOptions)ViewData["sort"]) %>
I have a need to change the default controller/action that’s generated by the sort method. For example,
defaultControllerName/defaultActionName/?Column=ProductId&Direction=Ascending
would change to
customControllerName/customActionName/?Column=ProductId&Direction=Ascending
I haven't been able to find any existing methods in the MVCcontribution classes that would allow me to customise the links. I’d appreciate any pointers on how to go about altering the default links as I’m still very much a MVC/C# newbie.
That's not an easy task. You will need a custom grid renderer to achieve this and override the RenderHeaderText method:
public class MyHtmlTableGridRenderer<T> : HtmlTableGridRenderer<T> where TViewModel : class
{
protected override void RenderHeaderText(GridColumn<TViewModel> column)
{
if (IsSortingEnabled && column.Sortable)
{
// TODO: generate a custom link here based on the sorting options
string text = ...
base.RenderText(text);
}
else
{
RenderText(column.DisplayName);
}
}
}
And then specify that the grid should use this renderer:
.RenderUsing(new MyHtmlTableGridRenderer<Employee>())
I wanted to provide a complete working example:
public class SortableHtmlTableGridRenderer<T> : HtmlTableGridRenderer<T> where T : class
{
readonly string _action;
readonly string _controllerName;
public SortableHtmlTableGridRenderer(string action, string controllerName)
{
_action = action;
_controllerName = controllerName;
}
protected override void RenderHeaderText(GridColumn<T> column)
{
if (IsSortingEnabled && column.Sortable)
{
string sortColumnName = GenerateSortColumnName(column);
bool isSortedByThisColumn = GridModel.SortOptions.Column == sortColumnName;
var sortOptions = new GridSortOptions
{
Column = sortColumnName
};
if (isSortedByThisColumn)
{
sortOptions.Direction = (GridModel.SortOptions.Direction == SortDirection.Ascending)
? SortDirection.Descending
: SortDirection.Ascending;
}
else //default sort order
{
sortOptions.Direction = column.InitialDirection ?? GridModel.SortOptions.Direction;
}
var routeValues = HtmlHelper.AnonymousObjectToHtmlAttributes(new {sortOptions.Column, sortOptions.Direction });
var text = HtmlHelper.GenerateLink(Context.RequestContext, RouteTable.Routes, column.DisplayName, null, _action, _controllerName, routeValues, null);
RenderText(text);
}
else
{
RenderText(column.DisplayName);
}
}
}
Usage:
.RenderUsing(new SortableHtmlTableGridRenderer<YourModelType>("Search", "Search"))

Resources