ago 4

Olá,

Hoje vos escrevo sobre algo básico, porém útil, mas que ninguém que trabalha com Rails soube me responder.

Trata-se da passagem de todos os campos do form direto para um objeto, mas tudo isso em 1 linha de código, Ohhhh!!

Esse código é gerado pelo scaffolding do Rails, mas fazendo o administrativo do site na mão (pois o scaffolding é básico e ninguém realmente usa isso) precisei disso, de passar tudo direto para o objeto sem precisar escrever atributo por atributo, então segue ai um exemplo da estrutura que os campos do form precisam ter para analisar-mos.

<input name=”id” value=”150″ type=”hidden” />

<input name=”dados[nome]” value=”teste” type=”text” maxlenght=”50″ />

<input name=”dados[ativo]” value=”1″ type=”checkbox” />

Vamos supor que tenhamos uma classe chamada Cliente que possui os atributos:

nome [varchar: 50]

ativo [tinyint: 1]

Para jogar-mos esses dois atributos para uma instância da classe Cliente e gravar no banco precisamos fazer assim no Rails:

cliente = Cliente.new(params[:dados])

cliente.save

e para alterar os atributos de um Cliente já existente, usamos:

cliente = Cliente.find(params[:id])

cliente.update_attributes(params[:dados])

#não precisa do cliente.save, pois o método update_attributes já faz isso por você

Agora, a explicação é bem simples, quando você cria um array de campos e cada campo tem o nome de um atributo da classe final, quando você passar este array por parâmetro o Ruby on Rails vai verificar e jogar automaticamente os campos do form para cada atributo do objeto.

Então se tempo no form um campo chamado dados[nome] e em nome classe temos o atributo nome, na passagem dos dados automaticamente o atributo nome recebe o valor do campo dados[nome].

Pelo scaffold, ele cria os forms contendo o nome do array sendo o nome da classe, então se você gerar um scaffold para cliente, ele vai gerar os nomes dos campos assim:  cliente[nome], cliente[ativo].

Mas isso pouco importa, pois o nome do array não muda em nada, apenas trocariamos de:

Cliente.new(params[:dados])

para

Cliente.new(params[:cliente])

Para economizar trabalho, eu sempre crio os forms com os mesmos nomes de campos, assim quando vou criar um form igual apenas copio as mesmas views e está tudo certo, sei que o nome do array sempre será dados, mas isso é de cada um, o importante é entender o funcionamento.

Espero que tenham gostado, pois isso é algo que dificilmente você encontrará explicando por ai, eu mesmo não achei, só testando o scaffold mesmo para notar isso.

—————————————————————————————-

Estou editando o post pois um amigo (Marcus Vinicus) da lista rails-br me alertou sobre uma forma de hackearem sua aplicação através desta facilidade chamada mass-assignment que foi explicada acima.

Vou tentar explicar o funcionamento de como alguém pode burlar uma aplicação usando o mass-assignment e como podemos nos proteger facilmente com o Rails.

Bom, como expliquei, os valores dos campos são passados diretamente para o objeto, mas nós só colocamos em nosso form os campos nome e ativo, e se tivessemos um atributo em nossa classe chamado admin, ficando assim nossa estrutura:

nome [varchar: 50]

ativo [tinyint: 1]

admin [tinyint: 1]

Sendo que em nosso form só temos 2 campos e este campo admin nós não usamos ele no cadastro do registro nem na alteração, pois somente um usuário é admin e este usuário é um registro qualquer do nosso banco de dados que tem direito a fazer tudo na aplicação, então não precisamos disponibilizar em nosso form esse campo para informar se o usuário é admin ou não, já que decidimos que em nossa aplicação só tem 1 admin e ele já está lá com o valor 1 neste campo da tabela.

Mas ai, vamos supor que um engraçadinho, usando o Firebug do Firefox editou o html e adicionou em nosso form que antes era:

<input name=”dados[nome]” value=”teste” type=”text” maxlenght=”50″ />

<input name=”dados[ativo]” value=”1″ type=”checkbox” />

e mudou para:

<input name=”dados[nome]” value=”teste” type=”text” maxlenght=”50″ />

<input name=”dados[ativo]” value=”1″ type=”checkbox” />

<input name=”dados[admin]” value=”1″ type=”text” />

E quando ele fez o submit no form, o Rails jogou tudo pro objeto Cliente, inclusive o valor do campo admin, e com isso atribuiu para o objeto Cliente o valor 1 para o atributo admin, fazendo com que aquele usuário seja também um administrador do sistema e tenha acesso a tudo.

Obviamente, o Rails sempre tem seus métodos de proteção, e agora vou explicar como permitir somente que alguns campos sejam definidos pelo mass-assignment.

Para fazer essa façanha super difícil, basta na sua classe você especificar assim (com base em nossa classe Cliente):

class Cliente < ActiveRecord::Base
attr_accessible :nome, :ativo
end

Com isso, estamos dizendo que em nossa classe Cliente, somente nos atributos nome e ativo é permitido usar o mass-assignment ou também podemos proibir os campos que não queremos que o mass-assignment atribua valores, assim:

class Cliente < ActiveRecord::Base
attr_protected :admin
end

Assim, estamos definindo em nossa classe Cliente que o campo admin está protegido e que não se pode usar o mass-assignment nele.

Bem simples né? Como tudo no Rails.

Obrigado ao Marcus pela dica do mass-assignment.

ago 2

Olá,

Assim como pregamos o que vivemos, eu também escrevo o que vivo no dia-a-dia e aprendo com as pessoas.

Então, a partir de uma necessidade de um amigo, pesquisei como seria para escrever um arquivo de texto simples, um TXT da vida, com o Ruby on Rails, na verdade só com o Ruby, e encontrei uma solução:

nome_arquivo = RAILS_ROOT + ‘/pasta/arquivo.txt’

arquivo = File.open(nome_arquivo, ‘wb’)
arquivo.puts “nome: Paulo”
arquivo.close

Caso você queira enviar este arquivo para download, existe o comando send_file que faz isto para você, assim:

#seguindo o exemplo acima

send_file nome_arquivo

Mas informações sobre o send_file:

http://api.rubyonrails.org/classes/ActionController/Streaming.html

Mas informações sobre a classe File:

http://corelib.rubyonrails.org/classes/File.html

ago 2

Olá,

Como todos sabem o JasperReports é uma das mais usadas (senão a mais usada) ferramenta para relatórios no mundo Java, além de ser OpenSource e de gerar o relatório em:  PDF, RTF, HTML, CSV and XML.

Como senão bastasse, tem também um editor de relatórios visuais muito usado e que particularmente eu achei ele perfeito para uma ferramenta grátis, pois muitos dizem ai que tudo o que é opensource/free é uma bosta, eu sempre discordei, mas sempre existiram as ovelhas negras, senão não tem graça, mas voltando…

A ferramenta para criação visual chama-se iReport.

De posse dessas maravilhosas ferramentas tem-se um grande produto em mãos para gerar QUALQUER tipo de relatório (eu até hoje não vi nenhum que não fosse possível gerar).

Então, deixo aqui como usar esta mesma ferramenta com o Ruby on Rails, já que o Jasper trabalha com arquivos XML e é em Java, o que possibilita sua fácil integração com qualquer linguagem e servidor.

http://wiki.rubyonrails.org/rails/pages/HowtoIntegrateJasperReports

Eu já tive um idéia mas não coloquei em prática, que seria deixar o JasperServer em um servidor já configurado só para ele, com um webservice em Java mesmo ou em outra linguagem só para receber um XML com o que tem que ser feito e o webservice processar esse XML enviado via webservice, gerar o relatório e retornar o link externo para acessar o relatório. Seria uma aplicação bem interessante, quem sabe um dia, não é nada difícil, mas é necessário um pouco de tempo para desenvovler tudo e por em prática.

Mas fica ai a dica para quem quiser, se precisar de ajuda, estamos ai.

———————————————————————

Só editando o post e acrescentando um detalhe:

Existe um plugin para o Netbeans que permite criação visual do relatório também, para quem quiser, está aqui:

http://jasperforge.org/plugins/project/project_home.php?group_id=241

ago 2

Olá,

Esse é um post rápido sobre um novo recurso NATIVO do kernel do Linux, o suporte a multitouch.

Próximos Posts »