porovnanie hodnot pri validacii formulára

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

Dobrý den,

Podarilo sa mi z formulara ziskat hodnoty a odoslat ich do modelu na spracovanie. Problémom je, že hodnoty potrebujem porovnať už s existujúcimi hodnotami.

takto vyzera moj dump($values) z formu

<?php
keywords => Nette\ArrayHash (3)
0 => Nette\ArrayHash (1)
word => "Slovo1" (6)
1 => Nette\ArrayHash (1)
word => "Slovo2" (6)
2 => Nette\ArrayHash (1)
word => "Slovo3" (6)

?>

v Submit metode si ich odoslem do modelu a tu ich spracovavam.
Problem je v tom ze potrebujem porovnat ci uz existuje dane slovo v databaze, ak ano, zisti jeho IDcko, ak nie, tak ho pridaj do databaze.

Toto je zrejme velmi jednoduche, ale stale som sa nedostal k tomu aby mi to islo bez problemov.

<?php

	$slova = $this->getkeyword(); // zistim si vsetky slova, ktore su v databazi

           foreach ($keywords as $id => $klucslovo)
           {

           if(in_array($klucslovo['word'],$slova)){      // tuto potrebujem upravit podmienku
	      $slovo = $klucslovo['word'];
              $idslovo = $this->getIdKeyWord($slovo); // zistim ID existujuceho slova
              echo "Slovo existuje, posuvam ti idcko";
            } else {
                 $row = $this->database->table('key_word')->insert(array(
                                 'word'=>$klucslovo,
                                ));
                     $idslovo = $row->id_key_word;
                     echo "slovo neexistuje, pridavam do databaze";
            }
?>

Potrebujem zistit, co ti ide jednoduchsie, alebo kde je chyba, pretoze ta podmienka sa mi stale vyhodnocuje stale zle, tak som dufal ze mi pomozete. Dakujem.

Jan Mikeš
Člen | 771
+
0
-

Jdes na to spatne. Co budes delat v okamziku, kdy budes mit 100000 slov v databazi? Budes po kazdem requestu zbytecne selectovat vsech 100k slov a prochazet pole s 100k polozkami?

	// Tohoto se zbav
	// $slova = $this->getkeyword(); // zistim si vsetky slova, ktore su v databazi

A zkus neco takovehoto (jedna se o nastrel, urcite to zvladnes dotahnout):

foreach($keywords as $word){
	$row = $this->myModel->getOneKeyword($word);
	if(!$row){
		/** @var Nette\Database\Table\ActiveRow **/
		$newRow = $this->myModel->insert(array(
			"word" => $word
		));
		$this->flashMessage("Slovo $newRow->word bylo pridano do DB a ma id $newRow->id");
	}
	else {
		$this->flashMessage("Slovo $row->word uz v DB davno je a ma id $newRow->id");
	}
}
attika8
Člen | 23
+
0
-

Paráda, dik moc. Nad tym som prave rozmyslal, ze potom s velkou databazou to bude problem, takto je to super. Dik.

Editoval attika8 (18. 3. 2013 23:32)

Jan Mikeš
Člen | 771
+
0
-

Dalo by se to jeste vymyslet tak, aby se ti generoval pouze 1 dotaz (1 nebo 3, to uz zas takovy rozdil neni, s temi 100k by to bylo horsi). Ten dotaz by pak vypadal nejak takto:

SELECT id, word FROM key_word WHERE id IN (1, 2, 3)

Docilit toho lze asi nejsnaze takto:

$keywords = array(1, 2, 3);
$this->myModel->searchWordsFromArray($keywords);

// Implementace v modelu
protected function searchWordsInArray( array $words ){
	return $this->database->table("key_word")->where("key_word", $words);
}

Ale mel by jsi potom slozitejsi porovnavani jake slovo nalezeno bylo a jake ne, musel by sis s tim vice pohrat, je to jen na tobe, jestli chces mit co nejmene dotazu do DB, nebo to nepotrebujes mit az tak moc optimalizovano na rychlost (v radu par ms).

Editoval Lexi (18. 3. 2013 23:38)