Uma das razões que nos faz utilizar uma framework é poupar tempo. Porém, as vezes é preciso fazer algumas adaptações para melhorarmos ainda mais a eficiência no desenvolvimento da aplicação. É aí que a framework precisa oferecer flexibilidade.
Como já disse anteriormente, estou utilizando o Code Igniter para desenvolver um projeto pessoal, e vou mostrar o princípio de uma pequena adaptação que vai me poupar muito tempo e várias linhas de código.
A framework possui uma funcionalidade chamada Active Records, que simplifica os comandos básicos de acesso ao banco (Select, Update, Delete e Insert). Veja um exemplo de um Insert, tirado do próprio user guide:
$data = array(
'title' => $title,
'name' => $name,
'date' => $date
);
$this->db->insert('mytable', $data);
Simples, porém, pra utilizar este método dentro de um método inserir() numa classe de modelo, eu preciso sempre especificar a tabela e seus campos em um array com seus respectivos valores.
Utilizando Modelos que representam as Tabelas do meu banco, isto é, a classe conter atributos iguais aos campos das tabelas, podemos criar uma estensão da classe Model para não ter trabalho com estes métodos, e fazer nossos modelos estenderem desta nova classe.
O código abaixo deverá ser colocado num arquivo chamado MY_Model.php dentro do diretório application\libraries, que o CI se encarrega de carregá-la pra você (1).
class MY_Model extends Model
{
var $nmTabela;
var $nmCampoId;
/**
* metodo construtor da classe
* @param [str] nome da tabela do objeto
* @param [str] nome do campo identificador do objeto
*/
function MY_Model($nmTabela, $nmCampoId)
{
$this->nmTabela = $nmTabela;
$this->nmCampoId = $nmCampoId;
parent::Model();
}
/**
* metodo de insercao no banco
* @param [arr] array com os dados do objeto para insercao do banco
* @return [boo] sucesso ou falha no processo
*/
function inserir($arrDados)
{
$atributos = get_class_vars( get_class($this) );
foreach ($atributos as $nmAtributo => $valor)
{
if ( ($nmAtributo != 'nmTabela') && ($nmAtributo != 'nmCampoId') )
$this->$nmAtributo = $arrDados[$nmAtributo];
}
return $this->db->insert('usuarios', $this);
}
}
Dessa forma, toda classe de modelo da sua aplicação terá um método inserir() onde você só precisa passar por parâmetro um array (provavelmente vindo de um formulário) com o nome dos campos da classe e seus valores. O método se encarrega de definir os valores para os atributos do objeto e chamar a função de inserção.
Como o artigo ficou um pouco grande, resolvi omitir os métodos alterar() e excluir(), mas o arquivo completo está disponível para download aqui. Este foi apenas um exemplo simples do que podemos fazer em cima de uma boa estrutura.
(1) – Apesar do que diz o manual, o Code Igniter não carrega o MY_Model automaticamente. E não adianta também usar o autoload, pois ali o Model ainda não foi carregado. Você pode criar um MY_Controller que executa a chamada do MY_Model automaticamente, usando: $this->load->model('model');. Acredito que seja um bug do CI, mas ainda vou verificar com mais calma.
ATENÇÃO: No meu entendimento existe um BUG no framework em relação ao carregamento do MY_Model, conforme observação acima. A solução foi reportada para a equipe do CI, mas não tive retorno. A quem interessar, veja mais informações no artigo do BUG no Loader de Models.
#1 by Ricardo Amorim - December 1st, 2006 at 09:44
Muito útil e bacana.
Vou implementar estas funcionalidades no meu framework, o que eu sempre digo, é preciso programar apenas uma vez, depois é só reutilizar, isto nos poupa tempo e dor de cabeça.
Parabéns!
#2 by Reginaldo Sousa - June 1st, 2007 at 00:09
Olá Newton,
O link para o arquivo MY_Model.php está quebrado.
Você pode me enviar este arquivo por email?
Estou começando agora com CI.
#3 by Welson Santos - August 10th, 2009 at 17:37
Boa Tarde Newton eu estava tentar fazer um classe MY_Model e nao funcionou eu salvei exatamento com o nome de MY_Model.php e dentro da pasta application/liberies porem não funcionou
#4 by newton - August 10th, 2009 at 18:06
Welson,
Verifique no seu arquivo de configuração, pois nele existe o prefixo que deve ser utilizado, que por padrão vem o “MY_”. Se você tiver configurado pra algo diferente, terá de usar o seu padrão.
Outra cosia que você tem de se atentar é ao último parágrafo do meu texto, em relação ao carregamento do MY_Model, que eu cheguei a conclusão de que poderia ser um bug, e informei a correção necessária aqui: http://www.newtonwagner.net/framework/bug-estendendo-o-code-igniter-my_model/
O Code Igniter teve várias atualizações desde o dia em que escrevi estes artigos, então podem haver algumas diferenças, principalmente no código de correção do “bug”.
Caso esse problema realmente ainda exista na última versão do CI, aconselho a tentarem novamente reportá-lo à equipe de desenvolvimento do framework.
#5 by Jonas Ruth - October 8th, 2009 at 00:11
Também me deparei com esse problema de ele não carregar automaticamente o Model quando criado o MY_Model.
Ouvi falar (não testei) que se retirar o MY_ do inicio ele carrega automaticamente mesmo.
Creio que seja um erro da documentação somente. Pois nem sempre podemos querer que todos os models herdem o My_Model indiretamente, assim fica mais flexível e podemos criar um My_Model_B.