CakePHP - Salvando dados HABTM

90 views
Skip to first unread message

Wagner Franze Junior

unread,
Nov 15, 2009, 3:59:19 PM11/15/09
to Cake PHP Português
Boa tarde,

Estou salvando dados HABTM e estou com um único problema. Meu
formulário possui um campo do tipo text para que seja informdo o nome
do livro e uma lista de categorias exibidas através de checkbox para
que o usuário possa associar o livro a essas categorias. Essa listagem
de categorias é dinâmica porque pode ser cadastradas novas categorias
e essas devem ser axibidas. O problema que esta acontecendo é que,
quando vou salvar o novo livro com suas associações de categorias, ele
gera também inserts para as categorias que não foram selecionadas,
porém, esse inserts gerados para as categorias que não foram
selecionadas tem o id da categoria definido como 0. Quando ele tenta
fazer o insert ele apresenta erro dizendo que esse id não existe na
tabela de cetegorias.

Exemplo do que ele gera:
Query: INSERT INTO `categorias_livros` (`categoria_id`, `livro_id`)
VALUES (0, 5)

Com isso ele apresenta o seguinte erro:

Warning (512): SQL Error: 1452: Cannot add or update a child row: a
foreign key constraint fails (`cakestudo`.`categorias_livros`,
CONSTRAINT `fk_categorias_llivros_categorias1` FOREIGN KEY
(`categoria_id`) REFERENCES `categorias` (`categoria_id`) ON DELETE NO
ACTION ON UPDATE NO ACTION) [CORE\cake\libs\model\datasources
\dbo_source.php, line 525]

Code | Context

$sql = "INSERT INTO `categorias_livros` (`categoria_id`, `livro_id`)
VALUES (0, 5)"
$error = "1452: Cannot add or update a child row: a foreign key
constraint fails (`cakestudo`.`categorias_livros`, CONSTRAINT
`fk_categorias_llivros_categorias1` FOREIGN KEY (`categoria_id`)
REFERENCES `categorias` (`categoria_id`) ON DELETE NO ACTION ON UPDATE
NO ACTION)"
$out = null

$out = null;
if ($error) {
trigger_error("<span style = \"color:Red;text-
align:left\"><b>SQL Error:</b> {$this->error}</span>",
E_USER_WARNING);

DboSource::showQuery() - CORE\cake\libs\model\datasources
\dbo_source.php, line 525
DboSource::execute() - CORE\cake\libs\model\datasources
\dbo_source.php, line 201
DboSource::create() - CORE\cake\libs\model\datasources\dbo_source.php,
line 585
Model::save() - CORE\cake\libs\model\model.php, line 1253
Model::__saveMulti() - CORE\cake\libs\model\model.php, line 1364
Model::save() - CORE\cake\libs\model\model.php, line 1266
Model::__save() - CORE\cake\libs\model\model.php, line 1658
Model::saveAll() - CORE\cake\libs\model\model.php, line 1562
LivrosController::add() - APP\controllers\livros_controller.php, line
16
Object::dispatchMethod() - CORE\cake\libs\object.php, line 116
Dispatcher::_invoke() - CORE\cake\dispatcher.php, line 227
Dispatcher::dispatch() - CORE\cake\dispatcher.php, line 194
[main] - APP\webroot\index.php, line 88


Essa tentativa de inserir a categoria que não foi selecionada não
prejudica a execução do cadastro do novo livro e a associação com as
categorias selecionadas, mas não quero que esse erro continue.

Existe alguma forma de dizer para o cakePHP que não tente inserir as
categorias que não foram selecionadas no formulário?



Abaixo segue como se encontra o meu arquivo de controller para a
tabela Livros:

<?php

class LivrosController extends AppController{

var $name = 'Livros';
var $helpers = array( 'Html' , 'Form' , 'Javascript' , 'Ajax' );
var $uses = array( 'Categoria', 'Livro' );

function index(){
$this->set('Livros', $this->Livro->find('all', array
( 'Livro.livro_id' , 'Livro.nome' )));
}

function add(){
$this->set('Categorias', $this->Categoria->find('all', array
( 'Categoria.categoria_id' , 'Categoria.nome' )));

if( $this->Livro->saveAll( $this->data )){
print_r( $this->data );
}
}

}

?>



Segue código do model da minha tabela livros:

<?php


class Livro extends AppModel{

var $name = 'Livro';
var $primaryKey = 'livro_id';
var $hasAndBelongsToMany = array( 'Categoria' => array
( 'className' => 'Categoria',
'joinTable' => 'categorias_livros',
'foreignKey' => 'livro_id',
'associationForeignKey' => 'categoria_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => '' ) );

}
?>


Segue a view para a ação de adicionar novo livro e que gera o
formulário:

<?php

print $form->create('Livro');

print $form->input('Livro.nome', array( 'type' => 'text' , 'label'
=> 'Nome' ));

print '<ul>';
$cont = 0;
foreach( $Categorias as $c ):
print $form->input( 'Categoria.' . $cont . '.categoria_id' , array
( 'type' => 'checkbox', 'label' => false , 'value' => $c['Categoria']
['categoria_id'], 'before' => '<li>', 'after' => $c['Categoria']
['nome'] . '</li>' ));
$cont++;
endforeach;
print '</ul>';

print $form->end('Gravar');

?>




Edinei L. Cipriani

unread,
Nov 19, 2009, 6:55:30 AM11/19/09
to cake-...@googlegroups.com
Olá amigo, não use o uses, ele vai ficar obsoleto, use classRegistry,

Poste o model habtm, para verificar

2009/11/15 Wagner Franze Junior <franze...@gmail.com>



--
Edinei L. Cipriani
Blog: http://phpedinei.wordpress.com
Twitter: http://www.twitter.com/phpedinei

Desenvolvedor Colégio Trilingue Inovação
Site: http://www.colegioinovacao.com.br
Cursando Sistemas de Informação  - Unoesc Chapecó 1 Período
Integrante do grupo Fool N Lost de algoritimos computacionais
Fone 49 84149086

Danilo Miguel

unread,
Nov 19, 2009, 6:59:08 AM11/19/09
to cake-...@googlegroups.com
>> Olá amigo, não use o uses, ele vai ficar obsoleto, use classRegistry,

Onde tem uma referência para isso?


Danilo Miguel - www.dimiguel.com.br
E-mail/MSN: dimi...@gmail.com
Skype: dimiguel.com.br
+55 35 9123.7290


2009/11/19 Edinei L. Cipriani <phpe...@gmail.com>

Wagner Franze Junior

unread,
Nov 19, 2009, 6:13:58 PM11/19/09
to cake-...@googlegroups.com
Oi Edinei...

Valeu, vou trocar..

Obrigado!

2009/11/19 Edinei L. Cipriani <phpe...@gmail.com>
Olá amigo, não use o uses, ele vai ficar obsoleto, use classRegistry,
Reply all
Reply to author
Forward
0 new messages