Como recuperar dados de uma viewer de outro controller
28/03/2008 00:00
0
Olá Pessoal,

Estou iniciando minha jornada no mundo Grails e estou tentando desenvolver um cadastro de clientes, onde existe a possibilidade do cliente ter cadastrado vários endereços. Consegui fazer a viewer para a inclusão e edição sem problemas. O que eu gostaria de fazer é que viewer com action show, que além de visualizar os dados dos clientes, eu possa ver também todos os endereços desses clientes que já estão cadastrados, como se fosse um action list mas dentro de um action show.

No meu controller onde exibo os dados do cliente estou tentando fazer assim:




def show = {

def customer = Customer.get( params.id )

if(!customer) {
flash.message = "Customer not found with id ${params.id}"
redirect(action:list)
}
else {
def customerAddress = CustomerAddress.findAllByCustomerId(params.id)
if (customerAddress) {
[ customerAddressList: customerAddress.list() ]
}
return [ customer : customer, custormerAddress : customerAddress ]
}
}



Na viewer coloquei esse código html:


<div class=&quot;nav&quot;><span class=&quot;menuButton&quot;><g&#58;link class=&quot;create&quot; controller=&quot;customerAddress&quot; action=&quot;create&quot; id=&quot;$&#123;customer.id&#125;&quot;>New CustomerAddress</g&#58;link></span></div>
<div class=&quot;list&quot;>
<table>
<thead>
<tr>


<g&#58;sortableColumn property=&quot;title&quot; title=&quot;Title&quot; />


<g&#58;sortableColumn property=&quot;gender&quot; title=&quot;Gender&quot; />

<g&#58;sortableColumn property=&quot;address&quot; title=&quot;Address&quot; />

<g&#58;sortableColumn property=&quot;number&quot; title=&quot;Number&quot; />

</tr>
</thead>
<tbody>
<g&#58;each in=&quot;$&#123;customerAddressList&#125;&quot; status=&quot;i&quot; var=&quot;customerAddress&quot;>
<tr class=&quot;$&#123;(i % 2) == 0 ? 'odd' &#58; 'even'&#125;&quot;>

<td><g&#58;link action=&quot;show&quot; id=&quot;$&#123;customerAddress.id&#125;&quot;>$&#123;customerAddress.title?.encodeAsHTML()&#125;</g&#58;link><</td>


<td>$&#123;customerAddress.gender?.encodeAsHTML()&#125;</td>

<td>$&#123;customerAddress.address?.encodeAsHTML()&#125;</td>

<td>$&#123;customerAddress.number?.encodeAsHTML()&#125;</td>

</tr>
</g&#58;each>
</tbody>
</table>
</div>



Onde customer são os dados recuperados dos clientes a partir do banco e customerAddress são os dados dos endereços dos clientes também recuperados a partir do banco de dados.

Acontece que ao tentar executar a minha action show o seguinte acontece pra mim:

Message: No property found for name [customerId] for class [class CustomerAddress]
Caused by: org.codehaus.groovy.grails.exceptions.InvalidPropertyException: No property found for name [customerId] for class [class CustomerAddress]
Class: CustomerController
At Line: [33]
Code Snippet:
33: def customerAddress = CustomerAddress.findAllByCustomerId( params.id )
34: if (customerAddress) {


O relacionamento entre customer e customerAddress é feito pelos campos:

id, na tabela customer
customer_id, na tabela customer_address

A consulta está sendo feita pela HQL = CustomerAddress.findAllByCustomerId(params.id).

Eu já tentei para saber o que pode estar acontecendo, mas estou com uma grande dificuldade de fazer isso. Alguém pode dar um help em como tentar resolver uma situação dessa?

Um grande abraço,

Rogério Carrasqueira
Tags: Grails


0
O problema é que usando os métodos dinâmicos de busca o grails não busca em propriedades dentro de propriedades diretamente ( customerAddress.customer.id ).

No seu caso vc tem algumas opções:


def customerAddress = CustomerAddress.findAllByCustomer( Customer.get( params.id ) )


ou


def customerAddress = CustomerAddress.findAll( 'from CustomerAddress ca where ca.customer.id = ?', [ params.id ] )


Mais detalhes aqui

[]'s

Rodrigo Auler
28/03/2008 00:00


0
Se a sua classe Customer possui uma relacao de CustomerAddess, entao a busca nem seria necessaria, pois o hibernate traz os enderecos do cliente pra vc, se vc precisar (ele usa inicializacao lazy por padrao).

Ex.:

class Customer&#123;
static hasMany = [addresses&#58;CustomerAddress]
&#125;

class CustomerAddress&#123;
static belongsTo = Customer
&#125;



Desta forma, na sua VIEW (é view, não viewer ok?), vc poderia acessar diretamente os endereços a partir do seu objeto de cliente:

Seu controlador ficaria assim:

def show = &#123;
def customer = Customer.get( params.id )

if(!customer) &#123;
flash.message = &quot;Customer not found with id $&#123;params.id&#125;&quot;
redirect(action&#58;list)
&#125;
return [ customer &#58; customer]
&#125;
&#125;


E a sua view teria:


<g&#58;each in=&quot;$&#123;customer?.addresses&#125;&quot; status=&quot;i&quot; var=&quot;customerAddress&quot;>


Abcs
Felipe
30/03/2008 00:00


0
Olá pessoal,

Novamente com a mesma questão porém apresentada de uma forma diferente.

Eu tenho duas classes: Customer e CustomerAddress, a relação entre essas classes é que um Customer poder ter vários CustomerAddress e um CustomerAddress deve ser estabelecido como principal para o Customer. Declarando fica basicamente assim:


No arquivo Customer.groovy no diretório domains


class Customer &#123;

static hasMany = [ customerAddress &#58; CustomerAddress ];

String firstName
String lastName
String email
String cpf
CustomerAddress currentAddress
String phone
Date dateCreated
Date lastUpdated

static def constraints = &#123;

email(email&#58;true,blank&#58;false,unique&#58;true)
firstName(maxSize&#58;50,blank&#58;false,nullable&#58;false)
lastName(maxSize&#58;50,blank&#58;false,nullable&#58;false)
currentAddress(nullable&#58;true)
cpf(maxSize&#58;15,nullable&#58;false,unique&#58;true)

&#125;

&#125;


Arquivo CustomerAddress.groovy também no diretório Domains



class CustomerAddress &#123;

static belongsTo = [ customer&#58;Customer ]

Customer customer
String address
String number
String complement
String suburb
Date dateCreated
Date lastUpdated

static def constraints = &#123;

customer()
address(maxSize&#58;80, blank&#58;false, nullable&#58;false)
number(maxSize&#58;10, blank&#58;false, nullable&#58;false)
complement(maxSize&#58;30, blank&#58;false, nullable&#58;false)
suburb(maxSize&#58;30, blank&#58;false, nullable&#58;false)

&#125;

&#125;



Sendo que agora gostaria de criar num mesmo formulário, os campos para inclusão dos dados para este Cliente (Customer) e Seu endereço Default. O que eu fiz? Na action save dentro de CustomerController.groovy, criei uma ação com a seguinte codificação



def save = &#123; RegisterCommand cmd ->

def user = new Customer(params[&quot;customer&quot;])


def customerAddress = new CustomerAddress(params[&quot;customerAddress&quot;])
customerAddress.customer = user

Customer.withTransaction &#123; status ->

if(!user.hasErrors() &amp;&amp; user.save() &amp;&amp; !customerAddress.hasErrors() &amp;&amp; customerAddress.save()) &#123;


if (!user?.currentAddress) &#123;
Customer.executeUpdate(&quot;update Customer set currentAddress=? where id = ?&quot;,[ customerAddress.id, user.id ])
&#125;

render(&quot;OK&quot;)

&#125;
else &#123;
status.setRollbackOnly()
render(&quot;PROBLEMA&quot;)
&#125;
&#125;
&#125;



O problema é quando a instrução:


if (!user?.currentAddress) &#123;
Customer.executeUpdate(&quot;update Customer set currentAddress=? where id = ?&quot;,[ customerAddress.id, user.id ])
&#125;


vai ser executada ela é simplemente ignorada e o campo currentAddress permanece nulo, causando um grande problema de relacionamento entre essas bases de dados.

Já tentei fazer via save e nada!

user.currentAddress = customerAddress.id
user.save(flush&#58;true)


Coloquei logSql = true no dataSource e vi que o update é executado porém o campo currentAddress continua null.

Sendo assim, já não sei mais o que fazer. Alguém tem alguma dica do que pode ser isso? Será um bug do Grails?

Aguardo a ajuda dos amigos.

Abraços

Rogério
19/05/2008 00:00



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto