Dvojí vložení (insert) vložení záznamu do DB
- andros
- Člen | 145
Udělal jsem si v Nette svoji první aplikaci, která vychází z první výukové aplikace v dokumentaci. Při ručním plnění dat na produkčním serveru do DB se mi čas od času (ne pravidelně) stane, že se vkládaný záznam vloží 2×. Natvrdo jsem si zapnul laděnku a zde je krásně vidět že se vše provede 2x:
screen zde: http://prnt.sc/dt39yv
Připadá mi, že se tak stane vždy, když zpracování dotazu po odeslání formuláře trvá o něco déle než obvykle.
Poraďte prosím, jak postupovat při odhalení, v čem je problém.
Děkuji
- andros
- Člen | 145
Snad bude stačit toto:
protected function createComponentPostForm()
{
//$form = new Form;
$form = $this->form();
$form->addText('title', 'Titulek:')
->setRequired("vz=y");
$category = array();
$select = $this->database->table('category')->select('id')->select('name')->fetchAll();
foreach ($select as $id => $row) {
$category[$id] = $row['name'];
}
$form->addSelect('category', 'Kategorie:', $category)
->setPrompt('Zvolte kategorii')
->setRequired("Zadejte kategorii");
$form->addText('year','Rok')
->setRequired('Rok výroby je potřeba vyplnit');
$form->addText('csfd_id','Id ČSFD');
$form->addTextArea('content', 'Obsah:',NULL, 10);
$form->addSubmit('send', 'Uložit a publikovat');
$form->onSuccess[] = [$this, 'postFormSucceeded'];
return $form;
}
public function postFormSucceeded($form, $values)
{
if (!$this->getUser()->isLoggedIn()) {
$this->error('Pro vytvoření, nebo editování příspěvku se musíte přihlásit.');
}
$postId = $this->getParameter('postId');
if ($postId) {
$post = $this->database->table('posts')->get($postId);
$post->update($values);
} else {
$post = $this->database->table('posts')->insert($values);
}
$this->flashMessage('Příspěvek byl úspěšně publikován.', 'success');
$this->redirect('Homepage:default');
}
- andros
- Člen | 145
Tady je celý presenter:
<?php
namespace App\Presenters;
use Nette;
use Nette\Application\UI\Form;
class PostPresenter extends BasePresenter
{
/** @var Nette\Database\Context */
private $database;
public function __construct(Nette\Database\Context $database)
{
$this->database = $database;
}
protected function form() {
$form = new Form;
$renderer = $form->getRenderer();
$renderer->wrappers['controls']['container'] = NULL;
$renderer->wrappers['pair']['container'] = 'div class=form-group';
$renderer->wrappers['pair']['.error'] = 'has-error';
$renderer->wrappers['control']['container'] = 'div class=col-sm-8';
$renderer->wrappers['label']['container'] = 'div class="col-sm-1 control-label"';
$renderer->wrappers['control']['description'] = 'span class=help-block';
$renderer->wrappers['control']['errorcontainer'] = 'span class=help-block';
// make form and controls compatible with Twitter Bootstrap
$form->getElementPrototype()
->class('form-horizontal page-form')
->role('form');
$form->onRender[] = function ($form) {
foreach ($form->getControls() as $control) {
$type = $control->getOption('type');
if ($type === 'button') {
$control->getControlPrototype()->addClass('btn btn-primary');
$usedPrimary = TRUE;
} elseif (in_array($type, ['text', 'textarea', 'select'], TRUE)) {
$control->getControlPrototype()->addClass('form-control');
} elseif (in_array($type, ['checkbox', 'radio'], TRUE)) {
$control->getSeparatorPrototype()->setName('div')->addClass($type);
}
}
};
return $form;
}
public function renderShow($postId)
{
$post = $this->database->table('posts')->get($postId);
if (!$post) {
$this->error('Stránka nebyla nalezena');
}
$this->template->post = $post;
$this->template->comments = $post->related('comment')->order('created_at');
}
protected function createComponentCommentForm()
{
$form = new Form; // means Nette\Application\UI\Form
$form->addText('name', 'Jméno:')
->setRequired();
$form->addEmail('email', 'Email:');
$form->addTextArea('content', 'Komentář:')
->setRequired();
$form->addSubmit('send', 'Publikovat komentář');
$form->onSuccess[] = [$this, 'commentFormSucceeded'];
return $form;
}
public function commentFormSucceeded($form, $values)
{
$postId = $this->getParameter('postId');
$this->database->table('comments')->insert([
'post_id' => $postId,
'name' => $values->name,
'email' => $values->email,
'content' => $values->content,
]);
$this->flashMessage('Děkuji za komentář', 'success');
$this->redirect('this');
}
protected function createComponentPostForm()
{
//$form = new Form;
$form = $this->form();
$form->addText('title', 'Titulek:')
->setRequired("Vložte titulek stránky");
$category = array();
$select = $this->database->table('category')->select('id')->select('name')->fetchAll();
foreach ($select as $id => $row) {
$category[$id] = $row['name'];
}
$form->addSelect('category', 'Kategorie:', $category)
->setPrompt('Zvolte kategorii')
->setRequired("Zadejte kategorii");
$form->addText('year','Rok')
->setRequired('Rok výroby je potřeba vyplnit');
$form->addText('csfd_id','Id ČSFD');
$form->addTextArea('content', 'Obsah:',NULL, 10);
$form->addSubmit('send', 'Uložit a publikovat');
$form->onSuccess[] = [$this, 'postFormSucceeded'];
return $form;
}
public function postFormSucceeded($form, $values)
{
if (!$this->getUser()->isLoggedIn()) {
$this->error('Pro vytvoření, nebo editování příspěvku se musíte přihlásit.');
}
$postId = $this->getParameter('postId');
if ($postId) {
$post = $this->database->table('posts')->get($postId);
$post->update($values);
} else {
$post = $this->database->table('posts')->insert($values);
}
$this->flashMessage('Příspěvek byl úspěšně publikován.', 'success');
$this->redirect('Homepage:default');
}
public function actionEdit($postId)
{
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in');
}
$post = $this->database->table('posts')->get($postId);
if (!$post) {
$this->error('Příspěvek nebyl nalezen');
}
$this['postForm']->setDefaults($post->toArray());
}
public function actionCreate($title, $rok, $csfd)
{
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in');
}
$this['postForm']->setDefaults([
'title' => $title,
"year" => $rok,
'csfd_id' => $csfd
]);
}
}
- cvak
- Člen | 1
Mě se stává něco podobného. Jako příčinu jsem identifikoval
skutečně dvojité odeslání formuláře uživatelem, čili 2× klikne na
tlačítko, případně stiskně Enter a zárověň klikne na tlačítko.
Formulář se pak zpracuje, a něž se stihne přesměrovat, zpracuje se ještě
jednou.
S tím souvisí můj dotaz – lze nějak zabránit tomu, aby došlo k druhému zpracování formuláře ještě předtím, než se stihne přesměrovat? Řešil to někdo? Je na to nějaký trik?
Díky
- CZechBoY
- Člen | 3608
@cvak jo, javascriptem, nedávno se to tu řešilo
https://forum.nette.org/…ni-formulare