Jak mazat a editovat záznamy podle nového quickstartu?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
xciza
Člen | 194
+
0
-

Ahoj, zkouším svoji aplikaci podle nového quickstartu ale narazil jsem u mazání a editace dat v db.
Do teď jsem to dělal následně:

public function renderDeleteUzivatel($id = 0) {
    $this->template->uzivatel = $this->uzivatel->get($id);
    if (!$this->template->uzivatel) {
        $this->error('Položka nenalezena.');
    }
}

protected function createComponentDeleteFormUzivatel() {

    $form = new Form;
    $form->addSubmit('delete', 'Smazat')->setAttribute('class', 'default');
    $form->addSubmit('cancel', 'Cancel');
    $form->onSuccess[] = callback($this, 'deleteFormUzivatelSubmitted');
    $form->addProtection('Vypršel časový limit, odešlete formulář znovu.'); //Obrana před Cross-Site Request Forgery (CSRF)
    return $form;
}

public function deleteFormUzivatelSubmitted(Form $form) {
    if ($form['delete']->isSubmittedBy()) {
        $this->uzivatel->find($this->getParameter('id'))->delete();
        $this->flashMessage('Položka smazána.');
    }

    $this->redirect('default');
}

či editace:

public function renderEditUzivatel($id = 0) {
       $form = $this['uzivatelForm'];
       if (!$form->isSubmitted()) {
           $row = $this->uzivatel->get($id);
           if (!$row) {
               $this->error('Záznam nebyl nalezen');
           }
           $form->setDefaults($row);
       }
   }

public function uzivatelFormSubmitted(Form $form) {
       $id = (int) $this->getParameter('id');

       if ($id > 0) {
           $this->uzivatel->find($id)->update(array(
               'username' => $form->values->username,
               'password' => md5($form->values->password),
               'ucet' => $form->values->ucet
           ));
           $this->flashMessage('Uživatel upraven.', 'success');
       } else {

           $this->context->createUzivatel()->insert(array(
               'username' => $form->values->username,
               'password' => md5($form->values->password),
               'ucet' => $form->values->ucet
           ));
           $this->flashMessage('Uživatel přidán.', 'success');
       }
       $this->redirect('Uzivatele:default');
   }

Ale v novém quicstartu se k tomu nemohu dokousat. Zatím mám toto:
UserPresenter:

protected function createComponentDeleteForm() {
       $form = new Form;

       $form->addSubmit('delete', 'Smazat')->setAttribute('class', 'default');
       $form->addSubmit('cancel', 'Cancel');
       $form->onSuccess[] = callback($this, 'deleteFormSubmitted');
       $form->addProtection('Vypršel časový limit, odešlete formulář znovu.'); //Obrana před Cross-Site Request Forgery (CSRF)
       return $form;
   }

   public function deleteFormSubmitted(Form $form) {
       $this->usersRepository->deleteUser;

       $this->flashMessage('Položka smazána.');

       $this->redirect('Users:default');
   }

a userTable:

public function deleteUser($id) {
       return $this->getTable()->delete($id);


   }

Díky za rady

Taps
Člen | 169
+
0
-

A jaká chyba se ti vypisuje, případně jaký SQL dotaz ti zobrazuje laděnka ?

xciza
Člen | 194
+
0
-

Tak mazání jsem vyřešil, ale s editací mám problém. V presenteru mám toto:

public function renderEdit($id = 0) {
       $form = $this['userForm'];
           $row = $this->usersRepository->findBy(array('id' => $id));
           if (!$row) {
               $this->error('Záznam nebyl nalezen');
           }
           $form->setDefaults(array(
               'username' => $row->username

           ));
   }

Problém mě dělá naplnění formuláře daty z db. hlásí chybu:

Cannot read an undeclared property Nette\Database\Table\Selection::$username.

na řádku

'username' => $row->username
ViPEr*CZ*
Člen | 817
+
0
-

Nemá tam náhodou být ->get?

xciza
Člen | 194
+
0
-

když dám:

'username' => $row->get('username')

tak to žádnou chybu nevypíše a do formu se mě hodnota nenačte…

ViPEr*CZ*
Člen | 817
+
0
-

xciza napsal(a):

když dám:

'username' => $row->get('username')

tak to žádnou chybu nevypíše a do formu se mě hodnota nenačte…

No myslel jsem místo findBy ;-)

xciza
Člen | 194
+
0
-

aha :)

Ale to mě hodí chybu že danou metodu nemám ve třídě a vůbec nevím co do ni dat…

Andrasin
Člen | 29
+
0
-

Pokud jede podle quickstartu tak ne get, ale find, což je metoda z BaseModelu obalující právě get…

Ve tvém aktuálním zápisu ti chybí ->fetch(), přepiš to takto:

$row = $this->usersRepository->findBy(array('id' => $id))->fetch();

Nebo lépe, takto:

$row = $this->usersRepository->find($id);

Editoval Andrasin (12. 10. 2012 23:24)

enumag
Člen | 2118
+
0
-

@Andrasin: Máš tam chybu.

$row = $this->usersRepository->get($id);
ViPEr*CZ*
Člen | 817
+
0
-

Hmmm teď když koukám do githubu, tak tam taková metoda není. Ale nic nebrání si ji dopsat. ;-) Do třídy Repozitory https://github.com/…pository.php si přidejte public metodu:

public function get($id) {
   return $this->getTable()->get($id);
}

a pak samozřejmě to co jsem psal… namísto findBy použij get.

xciza
Člen | 194
+
0
-

Andrasin napsal(a):

Pokud jede podle quickstartu tak ne get, ale find, což je metoda z BaseModelu obalující právě get…

Ve tvém aktuálním zápisu ti chybí ->fetch(), přepiš to takto:

$row = $this->usersRepository->findBy(array('id' => $id))->fetch();

Díky, takhle to funguje.

Ještě mám problém s potvrzením editace.

V presenteru mám toto:

public function userFormSubmitted(Form $form) {
        $id = (int) $this->getParameter('id');
        if ($id > 0) {
            $this->usersRepository->updateUser($form->values->username, $form->values->password, $form->values->ucet);
            $this->flashMessage('Uživatel upraven.', 'success');
        } else {
            $this->usersRepository->createUser($form->values->username, $form->values->password, $form->values->ucet);
            $this->flashMessage('Uživatel přidán.', 'success');
        }


        $this->redirect('Users:default');
    }

A v userRepository:

public function updateUser($username, $password, $ucet) {
       $id = (int) $this->getTable()->find('id')->fetch();

	return $this->getTable()->find($id)->update(array(
                   'username' => $username,
                   'password' => md5($password),
                   'ucet' => $ucet
               ));
   }

Ale po odeslání formuláře do daného uživatele nezaktualizuje…

Filip Procházka
Moderator | 4668
+
0
-

@enumag: Nemá tam chybu, metoda get() tam schválně vůbec není.

xciza
Člen | 194
+
0
-

Ještě mám problém s potvrzením editace.

V presenteru mám toto:

public function userFormSubmitted(Form $form) {
        $id = (int) $this->getParameter('id');
        if ($id > 0) {
            $this->usersRepository->updateUser($form->values->username, $form->values->password, $form->values->ucet);
            $this->flashMessage('Uživatel upraven.', 'success');
        } else {
            $this->usersRepository->createUser($form->values->username, $form->values->password, $form->values->ucet);
            $this->flashMessage('Uživatel přidán.', 'success');
        }


        $this->redirect('Users:default');
    }

A v userRepository:

public function updateUser($username, $password, $ucet) {
       $id = (int) $this->getTable()->find('id')->fetch();

	return $this->getTable()->find($id)->update(array(
                   'username' => $username,
                   'password' => md5($password),
                   'ucet' => $ucet
               ));
   }

Ale po odeslání formuláře do daného uživatele nezaktualizuje…

nikdo neporadi s editaci?

enumag
Člen | 2118
+
0
-

@HosipLan: Že tam není metoda get vím už od ViPErCZ. Ale stejně tam má chybu. Metoda find tam totiž taky není a i kdyby byla tak by spíš než ActiveRow vracela Selection. Btw. co máš na mysli tím „schválně“? Připadá mi, že by tam ta metoda měla být.

xciza
Člen | 194
+
0
-

Mohli bysme se prosím vrátit k mému problému s editací?

Moc díky ;)

enumag
Člen | 2118
+
0
-

@xciza: Jestli to chápu dobře tak se ti nezaktualizuje záznam v databázi? V tom případě si zjisti:

  1. Jaký SQL dotaz se vygeneruje (debug bar)?
  2. Nemáš někde rollback transakce?
  3. Zavolá se vůbec metoda updateUser?
  4. Pokud zavolá, zavolá se se správnými parametry?
ViPEr*CZ*
Člen | 817
+
0
-

A to co napsal enumag je obecně aplikovatelné (s drobnými změnami) na jakýkoliv takovýto problém… prostě je obecně dobré se naučit procházet (analyzovat) si vlastní kód krok po kroku (debugování). Tak se člověk naučí … ;-)
Jinak jestli chcete něco vidět (např. jaký SQL dotaz se generuje), tak si ještě odstraňte přesměrování $this->redirect(‚Users:default‘);

enumag
Člen | 2118
+
0
-

V Nette 2.1 už ani není potřeba odstraňovat ten redirect. Nové Nette v tom případě zorazí několik debug barů, 1 za každý požadavek.

Pozn. Jsem jediný komu na fóru nefunguje CSS nebo je to problém fóra? :-)

Editoval enumag (16. 10. 2012 12:20)

frosty22
Člen | 373
+
0
-

Nejsi jediný – asi nový design :=) Se říká v jednoduchosti je krása..

enumag
Člen | 2118
+
0
-

Mám s tím jen jeden problém – přijdeme o zvýrazňování syntaxe. :-D

frosty22
Člen | 373
+
0
-

No alespoň ale začnou vznikat nějaké doplňky pro prohlížeč v duchu – „NetteForumBeautifier“ for Firefox :)

Jinak tedy řekl bych, že to je nastavením oprávnění na souboru:
style/phpbb_bluen.css?v=10

Buď špatná skupina/uživatel či nastavit chmod 755 :)

Jan Endel
Člen | 1016
+
0
-

nebo prostě schází počáteční lomítko ;).

jazby
Člen | 44
+
0
-

Náhodou je to takhle cool :). Po chvilce si člověk zvykne a ani to nepřijde divné.. Moderní layout :)

xciza
Člen | 194
+
0
-

enumag napsal(a):

@xciza: Jestli to chápu dobře tak se ti nezaktualizuje záznam v databázi? V tom případě si zjisti:

  1. Jaký SQL dotaz se vygeneruje (debug bar)?
  2. Nemáš někde rollback transakce?
  3. Zavolá se vůbec metoda updateUser?
  4. Pokud zavolá, zavolá se se správnými parametry?

Tak zpět k mému problému.

Debug bar vypíše dotaz se správnými hodnotami:
UPDATE users
SET username=‚Pokus‘, password=‚XY‘, ucet=‚admin‘
WHERE (id = 0)

Až na to že to neupdatuje u id 16 ale 0. Čili se nezupdatuje u toho správnýho usera.

enumag
Člen | 2118
+
0
-

Ono je to logický jak tak na to koukám… tenhle tvůj řádek je totiž úplný nesmysl:

$id = (int) $this->getTable()->find('id')->fetch();

Tohle ti vrátí FALSE což se přetypuje na nulu. Co by to podle tebe mělo dělat mi vážně není jasné. ;-)

Editoval enumag (16. 10. 2012 19:00)

xciza
Člen | 194
+
0
-

To byl spíš takový pokus.

Vrtám se v tom dál a udělal jsem následující úpravy:
presenter

<?php
public function userFormSubmitted(Form $form) {
        $id = $form['id']->getValue();
        if ($id > 0) {
            $this->usersRepository->updateUser($id, $form->values->username, $form->values->password, $form->values->ucet);
            $this->flashMessage('Uživatel upraven.', 'success');
        } else {
            $this->usersRepository->createUser($form->values->username, $form->values->password, $form->values->ucet);
            $this->flashMessage('Uživatel přidán.', 'success');
        }

        //$this->redirect('Users:default');
    }

?>

a userRepository:

<?php
public function updateUser($id, $username, $password, $ucet) {
        return $this->getTable()->where($id)->update(array(
                    'username' => $username,
                    'password' => $password,
                    'ucet' => $ucet
                ));

    }
?>

Ale takto se změní všechny uživatele na username toho upravovaného… Co vylepšit?

EDIT: Tak stačilo změnit

<?php
        return $this->getTable()->where($id)->update(array(
na
        return $this->getTable()->find($id)->update(array(
?>

A snad to bude i nadále dělat to co ma

Editoval xciza (16. 10. 2012 19:20)

enumag
Člen | 2118
+
0
-

Ono by to muselo být ->where('id', $id). To tvé ->where($id) ti do SQL přidá něco jako WHERE 4 (kde ta 4 je to $id), což je pro kladné $id vždy pravdivá podmínka, tedy něco jako if (TRUE) v PHP.

mildabre
Člen | 62
+
0
-

xciza napsal(a):

Tak mazání jsem vyřešil, ale s editací mám problém. V presenteru mám toto:

public function renderEdit($id = 0) {
       $form = $this['userForm'];
           $row = $this->usersRepository->findBy(array('id' => $id));
           if (!$row) {
               $this->error('Záznam nebyl nalezen');
           }
           $form->setDefaults(array(
               'username' => $row->username

           ));
   }

Problém mě dělá naplnění formuláře daty z db. hlásí chybu:

Cannot read an undeclared property Nette\Database\Table\Selection::$username.

na řádku

'username' => $row->username

Nedeklarovaná property username v objektu typu Selection – což je ten $row to znamená, že tam nemáš klíč username, ale třeba name – bude to asi ve struktuře databáze, mrkni do Admina do tabulky user zda tam někde je username.