Como adicionar propriedades dinamicamente nos domais e listar estas propriedades.
18/01/2013 14:13
1
Oi eu estou tentando adicionar propriedades dinamicamente em um Domain, e tentei assim :


ItemAvaliacao.list().each {
def nome = "$it.subClasse.descricao".concat("_").concat("$it.descricao").camelCase()
def nomePonto = "$it.subClasse.descricao".concat("_").concat("$it.descricao").camelCase().concat("Ponto")
if ( !CuboRelatorio.metaClass.getProperty(nome) ) {
CuboRelatorio.metaClass."$nome" = 0.0
CuboRelatorio.metaClass."$nomePonto" = 0
}
}


Agora eu queria ver uma forma de listar no meu objeto criado todas as propriedades que estão neste objeto para que eu possa testar no meu teste de integração se as propriedades estão sendo inseridas.
Tags: dinamicamente propriedades metaprogramação meta


0

Oi, Pedro.

CuboRelatorio tem algo relacionado à Cubo OLAP? Talvez não seja a hora de migrar seu DB para um banco "NoSQL"? Creio que seja mais intuitivo para lidar com situações como essa.

Abraços!
18/01/2013 19:00


0
É isso aí mesmo CarlosG, porém se eu conseguir isso aí eu consigo resolver o meu problema e como não tenho experiência com bancos NoSql, acho que o risco seria maior, pois a App já está rodando e preciso dessa rotina.
18/01/2013 19:13


0
Pedro,

você que que uma ou mais instâncias de CuboRelatorio tenham, em certo momento, propriedades adicionais além das que estão definidad nele?


0
Exatamente José Yoshiriro, eu gostaria de adicionar algumas propriedades em CuboRelatorio.
19/01/2013 17:20


1
Oi Pedro Henrique,

nestes casos em que preciso ficar adicionando novas classes de domínio, costumo pensar em adotar uma base de dados não relacional. Já pensou na possibilidade de usar um banco de dados baseado em documentos como MongoDB para lidar com estes casos?

Assim os novos atributos poderiam ser acessados como um hash por exemplo, e a persistência seria ordens de magnitude mais simples pra você.


0
Pedro, segue um exemplo:

class Pessoa {
String nome
}

// em outra classe
Pessoa p = new Pessoa()
p.metaClass.email='jjj@jjj.com'
p.metaClass.telefone='91-8888-7777'
println p.email
println p.telefone

def campo1 = "apelido"
def campo2 = "blog"
p.metaClass."$campo1"='yoshi'
p.metaClass."$campo2"='naotenho.blog.com'
println p."$campo1"
println p."$campo2"


Veja que mudei o metaClass na instância e não na classe.
Era isso que queria?


1
Pedro, sugiro algumas refatorações:

Em
def nome = "$it.subClasse.descricao".concat("_").concat("$it.descricao").camelCase()
def nomePonto = "$it.subClasse.descricao".concat("_").concat("$it.descricao").camelCase().concat("Ponto")


Troque os
"$it.subClasse.descricao" por "${it.subClasse.descricao}" e
"$it.descricao" por "${it.descricao}". Acredite, não é a mesma coisa. Quando não se usa "{}" você obtém apenas o "toString()" do que coloca após o "$".

Porém, na verdade, acredito que o seguinte código teria o mesmo efeito:

def nome = "${it.subClasse?.descricao}_${it.descricao.camelCase()}"
def nomePonto = "${nome}Ponto"


Ficou menor como vê... porém não sei se como você fez (com os "concat") tem melhor desempenho.


0
Só pra ter certeza que o NoSql seria realmente a solução eu vou colocar aqui o problema, eu tenho informações de Monitoramento(fazenda, data, monitor) que tem vários ponto(s)(monitoramento_id, latitude, longitude) que tem itens_monitoramento(ponto_id, item_avaliacao, valor).

Eu preciso mostrar como num cubo, o cruzamento da fazenda naquele dia em linha e em coluna todos os itens de avaliação e o seu total correspondente a aquele dia/fazenda na coluna correta, com um banco relacional isso é ruim pois a lista de itens de avaliação pode mudar e aí se eu tivesse uma tabela para armazenar isso ela mudaria, ou mesmo uma classe.

Minha idéia seria usar uma classe e colocar dinamicamente nela os itens de avaliação e poder montar um Service que processe as informações e preencha a classe com as propriedades e dados para que eu montasse uma view com base nesta classe, agora vem a pergunta será que eu consigo fazer isso mais facilmente com um banco NoSql ? de que tipo Grafo(Neo4J) ou Documento (MongoDb) ?
21/01/2013 12:02


0
Consegui colocar o Crosstab do Jasper para funcionar, fiz um SQL e tchan thcan tchan, cubo funcionando 100%, mas eu gostaria ainda de saber sobre o NoSQL pois podem aparecer outros problemas em que eles se encaixem.

Ou até mesmo este dependendo da performance da minha solução atual.

Muito obrigado.
21/01/2013 17:36


0
Oi Pedro Henrique,

eu costumo pensar em NoSQL quando penso em situações nas quais sejam geradas tabelas esparsas: estas nas quais muitos campos são preenchidos apenas em alguns registros.

Normalmente estas situações surgem quando você precisa ficar adicionando atributos em tempo de execução, ou seja, quando o modelo relacional (colunas fixas e restritivo) não se aplica.

No mais, se for para gerar cubos, teria de pensar na abordagem também, porque se for só para escrever consultas, o modelo relacional normalmente (nem sempre) é mais adequado por causa da sua própria natureza declarativa né?


0
Isso, eu li o seu post no blog e a planilha :-), muito legal, valeu.
21/01/2013 20:01


1
Li esses tempos no blog do Kico sobre a "verdadeira face do NoSQL"..

Eu era uma das pessoas que achava que esse movimento era CONTRA SQL e na verdade é o "Not ONly"

Para esse caso do Pedro, me parece ser também algo que aplique bem a solução não-relacional - embora nunca tenha feito algo assim.

MInha dúvida com relação ao framework do grails e NoSQL nessa situação do pedro complementada pelo Yoshiriro:


class Pessoa {
String nome
}

// em outra classe
Pessoa p = new Pessoa()
p.metaClass.email='jjj@jjj.com'
p.metaClass.telefone='91-8888-7777'
println p.email
println p.telefone

def campo1 = "apelido"
def campo2 = "blog"
p.metaClass."$campo1"='yoshi'
p.metaClass."$campo2"='naotenho.blog.com'
println p."$campo1"
println p."$campo2"


O scaffold do grails iria entender essas propriedades acrescentadas nessa nova pessoa de boa? e para outras que não possuem essas propriedades nem exibiria os forms?
22/01/2013 16:15


0
Oi Rafael,

excelente pergunta. Vou chutar: acho que não.
Isto porque o scaffolding é executado apenas no iniciar da aplicação se não me engano, aonde são descobertos os campos e os controladores são montados.

Não sei se isto teria o mesmo impacto na geração do gsp. Tá aí um belo momento de fazermos umas experiências hein?


0
Uma sugetão.


class CuboRelatorio{
Map props = [:]

def propertyMissing(String name) {
if(name.startsWith('_')){
this.props[name.substring(1)]
}else{
throw new MissingPropertyException(name)
}
}

def propertyMissing(String name, value) {
if(name.startsWith('_')){
this.props[name.substring(1)] = value
}else{
throw new MissingPropertyException(name)
}
}
}


Assim voce pode usar relatoro._nome124 = 'alguma coisa' e vai saber diferenciar campos dinâmicos de campos hard e nao vai precisar alterar o schema a cada novo campo.

O scaffold vai quebrar pq ele é baseado nem campos estaticos da classe. Para contornar isso é um pouco complicado, voce poderia estender o GrailsDomainClass, interceptar o carregamento e metaprogramação do Gorm e força-lo a usar esse nova classe em vez da padrão.
22/01/2013 18:56



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