[Resolvido] Relacionamento HABTM
Boa noite
Voltei a um problema sobre relacionamento HABTM, nesse caso o relacionamento para que os dados seja gravados esta perfeito e funcionária se não fosse um detalhe que preciso em minha modelagem.
Eu possuo um relacionamento de muitos para muitos entre a tabela Artigos e Categorias. Para o Cake efetuar esse relacionamento, precisa de uma terceira tabela intermediária que no meu caso chama-se Artigos_Categorias. Abaixo seguem as definições de cada tabela.
Tabela Artigos:
CREATE TABLE IF NOT EXISTS `mydb`.`artigos` (
`id` BIGINT NOT NULL AUTO_INCREMENT ,
`artigo_pai_id` BIGINT NULL ,
`ativo_id` BIGINT NOT NULL ,
`atualizacao_id` BIGINT NOT NULL ,
`cancelado_id` BIGINT NULL ,
`cadastro_id` BIGINT NOT NULL ,
`ds_titulo` VARCHAR(100) NOT NULL ,
`ds_texto` LONGTEXT NOT NULL ,
`ts_atualizacao` TIMESTAMP NOT NULL ,
`ts_cadastro` TIMESTAMP NOT NULL ,
`ts_inclusao` TIMESTAMP NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_artigos_ativos1` (`ativo_id` ASC) ,
INDEX `fk_artigos_cancelados1` (`cancelado_id` ASC) ,
INDEX `fk_artigos_usuarios1` (`cadastro_id` ASC) ,
INDEX `fk_artigos_usuarios2` (`atualizacao_id` ASC) ,
INDEX `fk_artigos_artigos1` (`artigo_pai_id` ASC) ,
CONSTRAINT `fk_artigos_ativos1`
FOREIGN KEY (`ativo_id` )
REFERENCES `mydb`.`ativos` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_cancelados1`
FOREIGN KEY (`cancelado_id` )
REFERENCES `mydb`.`cancelados` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_usuarios1`
FOREIGN KEY (`cadastro_id` )
REFERENCES `mydb`.`usuarios` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_usuarios2`
FOREIGN KEY (`atualizacao_id` )
REFERENCES `mydb`.`usuarios` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_artigos1`
FOREIGN KEY (`artigo_pai_id` )
REFERENCES `mydb`.`artigos` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Tabela Categorias:
CREATE TABLE IF NOT EXISTS `mydb`.`categorias` (
`id` BIGINT NOT NULL AUTO_INCREMENT ,
`ativo_id` BIGINT NOT NULL ,
`atualizacao_id` BIGINT NOT NULL ,
`cancelado_id` BIGINT NULL ,
`cadastro_id` BIGINT NOT NULL ,
`categoria_pai_id` BIGINT NULL ,
`categoriatipo_id` BIGINT NOT NULL ,
`ds_descricao` VARCHAR(100) NOT NULL ,
`ts_atualizacao` TIMESTAMP NOT NULL ,
`ts_cadastro` TIMESTAMP NOT NULL ,
`ts_inclusao` TIMESTAMP NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_categorias_ativos1` (`ativo_id` ASC) ,
INDEX `fk_categorias_cancelados1` (`cancelado_id` ASC) ,
INDEX `fk_categorias_usuarios1` (`cadastro_id` ASC) ,
INDEX `fk_categorias_usuarios2` (`atualizacao_id` ASC) ,
INDEX `fk_categorias_categorias1` (`categoria_pai_id` ASC) ,
INDEX `fk_categorias_categoriatipos1` (`categoriatipo_id` ASC) ,
CONSTRAINT `fk_categorias_ativos1`
FOREIGN KEY (`ativo_id` )
REFERENCES `mydb`.`ativos` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_categorias_cancelados1`
FOREIGN KEY (`cancelado_id` )
REFERENCES `mydb`.`cancelados` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_categorias_usuarios1`
FOREIGN KEY (`cadastro_id` )
REFERENCES `mydb`.`usuarios` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_categorias_usuarios2`
FOREIGN KEY (`atualizacao_id` )
REFERENCES `mydb`.`usuarios` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_categorias_categorias1`
FOREIGN KEY (`categoria_pai_id` )
REFERENCES `mydb`.`categorias` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_categorias_categoriatipos1`
FOREIGN KEY (`categoriatipo_id` )
REFERENCES `mydb`.`categoriatipos` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Tabela Artigos_Categorias:
CREATE TABLE IF NOT EXISTS `mydb`.`artigos_categorias` (
`id` BIGINT NOT NULL ,
`artigo_id` BIGINT NOT NULL ,
`ativo_id` BIGINT NOT NULL ,
`atualizacao_id` BIGINT NOT NULL ,
`cancelado_id` BIGINT NULL ,
`cadastro_id` BIGINT NOT NULL ,
`categoria_id` BIGINT NOT NULL ,
`ts_atualizacao` TIMESTAMP NOT NULL ,
`ts_cadastro` TIMESTAMP NOT NULL ,
`ts_inclusao` TIMESTAMP NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_artigos_categorias_artigos1` (`artigo_id` ASC) ,
INDEX `fk_artigos_categorias_categorias1` (`categoria_id` ASC) ,
INDEX `fk_artigos_categorias_ativos1` (`ativo_id` ASC) ,
INDEX `fk_artigos_categorias_cancelados1` (`cancelado_id` ASC) ,
INDEX `fk_artigos_categorias_usuarios1` (`cadastro_id` ASC) ,
INDEX `fk_artigos_categorias_usuarios2` (`atualizacao_id` ASC) ,
CONSTRAINT `fk_artigos_categorias_artigos1`
FOREIGN KEY (`artigo_id` )
REFERENCES `mydb`.`artigos` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_categorias_categorias1`
FOREIGN KEY (`categoria_id` )
REFERENCES `mydb`.`categorias` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_categorias_ativos1`
FOREIGN KEY (`ativo_id` )
REFERENCES `mydb`.`ativos` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_categorias_cancelados1`
FOREIGN KEY (`cancelado_id` )
REFERENCES `mydb`.`cancelados` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_categorias_usuarios1`
FOREIGN KEY (`cadastro_id` )
REFERENCES `mydb`.`usuarios` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_artigos_categorias_usuarios2`
FOREIGN KEY (`atualizacao_id` )
REFERENCES `mydb`.`usuarios` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Se olharem a tabela Artigos_Categorias, possuo campos que necessito atualizar como controle de atualizações feitas pelo usuário logado. Os campos cadastro_id, atualizacao_id, ts_atualizacao, ts_cadastro, ts_inclusa e ativo_id que precisam ser atualizado.
A ação do momento é a ação Add, estou tentando gravar os dados, mas o Cake não reconhece os campos que citei anteriormente na relação entre as duas tabelas Artigos e Categorias.
Seguem abaixo o código para o model da tabela Artigos:
<?php
class Artigo extends AppModel {
var $name = 'Artigo';
var $hasAndBelongsToMany = array( 'Categoria' => array( 'className' => 'Categoria',
'joinTable' => 'artigos_categorias',
'foreignKey' => 'artigo_id',
'associationForeignKey' => 'categoria_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => '' ) );
}
?>
Logo abaixo, segue também o código controller da tabela Artigos onde podem visualizar o método add:
<?php
class ArtigosController extends AppController{
var $name = 'Artigos';
var $helpers = array( 'Html' , 'Form' , 'Javascript' , 'Ajax' , 'Fck' );
var $paginate = array( 'limit' => 5 , 'page' => 1 );
var $layout;
var $Categoria;
var $Ativo;
function index(){
$this->layout = 'ArtigoListagem' ;
$this->Idioma->recursive = 0 ;
$this->set( 'Artigos' , $this->paginate()) ;
}
function add(){
$this->Categoria = ClassRegistry::init( 'Categoria' );
$this->Ativo = ClassRegistry::init( 'Ativo' );
$this->layout = 'ArtigoCadastro';
$this->set( 'Artigos' , $this->Artigo->find( 'all' , array( 'fields' => array( 'Artigo.id' , 'Artigo.ds_titulo' ) ) ) );
$this->set( 'Categorias' , $this->Categoria->find( 'all' ,
array( 'fields' => array( 'Categoria.id' , 'Categoria.ds_descricao',
'Categoria.categoriatipo_id'),
'order' => array( 'Categoria.categoriatipo_id asc' ) ) ) );
$this->set( 'Ativos' , $this->Ativo->find( 'all' , array( 'fields' => array( 'Ativo.id', 'Ativo.ds_descricao' ))));
$this->data['ArtigosCategoria'] ['ativo_id'] = 1;
$ativo = $this->data['Artigo'];
if( $ativo['ativo_id'] == 0 ) {
$this->data['Artigo']['ativo_id'] = Null;
}
if( $ativo['artigo_pai_id'] == 0 ) {
$this->data['Artigo']['artigo_pai_id'] = Null;
}
if( $ativo['cancelado_id'] == 0 ) {
$this->data['Artigo']['cancelado_id'] = Null;
}
$categoria = $this->data['Categoria'];
for( $i = 1 ; $i <= count( $categoria ) ; $i++ ){
if ( $categoria[$i]['categoria_id'] == 0 ){
$this->data['Categoria'] [$i]['categoria_id'] = Null;
}
}
print_r( $this->data) ;
if( $this->Artigo->saveAll( $this->data )){
print 'ok';
}
}
}
?>
Dando um print_r em $this->data é exibido o seguintes registros:
>
Array ( [Artigo] => Array ( [ds_titulo] => eeee [ds_texto] => eeeeeeeeeeeeeeee [artigo_pai_id] => [ativo_id] => 1 [atualizacao_id] => 1 [cadastro_id] => 1 [cancelado_id] => [ts_atualizacao] => 2009-12-03 21:12:41 [ts_cadastro] => 2009-12-03 21:12:41 [ts_inclusao] => 2009-12-03 21:12:41 ) [Categoria] => Array ( [1] => Array ( [categoria_id] => 1 ) [2] => Array ( [categoria_id] => 11 ) [3] => Array ( [categoria_id] => 10 ) [4] => Array ( [categoria_id] => 9 ) [5] => Array ( [categoria_id] => ) [6] => Array ( [categoria_id] => ) [7] => Array ( [categoria_id] => ) [8] => Array ( [categoria_id] => ) [9] => Array ( [categoria_id] => ) [10] => Array ( [categoria_id] => ) [11] => Array ( [categoria_id] => ) [12] => Array ( [categoria_id] => ) [13] => Array ( [categoria_id] => ) [14] => Array ( [categoria_id] => ) [15] => Array ( [categoria_id] => ) [16] => Array ( [categoria_id] => ) [17] => Array ( [categoria_id] => ) [18] => Array ( [categoria_id] => ) [19] => Array ( [categoria_id] => ) [20] => Array ( [categoria_id] => ) [21] => Array ( [categoria_id] => ) [22] => Array ( [categoria_id] => ) [23] => Array ( [categoria_id] => ) ) )
Os erros exibidos são os seguintes:
>
Warning (512): SQL Error: 1364: Field 'ativo_id' doesn't have a default value [CORE\cake\libs\model\datasources\dbo_source.php, line 525]
Query: INSERT INTO `artigos_categorias` (`ts_atualizacao`, `ts_cadastro`, `ts_inclusao`, `categoria_id`, `artigo_id`) VALUES ('CURRENT_TIMESTAMP', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 8)
Query: INSERT INTO `artigos_categorias` (`ts_atualizacao`, `ts_cadastro`, `ts_inclusao`, `categoria_id`, `artigo_id`) VALUES ('CURRENT_TIMESTAMP', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 11, 8)
Query: INSERT INTO `artigos_categorias` (`ts_atualizacao`, `ts_cadastro`, `ts_inclusao`, `categoria_id`, `artigo_id`) VALUES ('CURRENT_TIMESTAMP', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 10, 8)
Query: INSERT INTO `artigos_categorias` (`ts_atualizacao`, `ts_cadastro`, `ts_inclusao`, `categoria_id`, `artigo_id`) VALUES ('CURRENT_TIMESTAMP', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 9, 8)
O que eu quero saber é como definir aqueles valores, seja no model ou no controller, informando e permitindo que o Insert seja criado adequadamente para a tabela Artigos_Categorias?
Considerando que eu preciso desse campos existindo na tabela Artigos_Categorias para controle de atualizações, não podendo excluir eles.
Obrigado a todos
Discussão (1)
Carregando comentários...