databáze místo query použít selection

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

Zdravím,
prosím o radu.
Místo klasického database query

$query = 'SELECT
      '.$this->table.'.'.$this->primary_key.',
      '.$this->table.'.created_when,
      '.$this->table.'.active,
      '.$this->table.'.id_login,
      '.$this->table_desc.'.id_language,
      '.$this->table_desc.'.name,
      '.$this->table_desc.'.description
    FROM '.$this->table.'
    INNER JOIN '.$this->table_desc.' ON
      ('.$this->table.'.'.$this->primary_key.' = '.$this->table_desc.'.'.$this->primary_key.')
    ';
$res = $this->database->query($query);
$this->template->posts = $res->fetchAll();

bych rád použil něco v tom smyslu jako $this->database->table(‚news‘)->where(),–>select(),… jenze mi to stale hlasi chyby…

takto vypada trida

<?php

namespace App\Presenters;

use Nette,
  App\Model;


/**
 * News presenter.
 */
class NewsPresenter extends BasePresenter
{
  /** @var Nette\Database\Context */
  private $database;
  private $table            = 'news';
  private $table_desc       = 'news_desc';
  private $primary_key      = 'id';
  private $primary_key_desc = 'id';


  public function __construct(Nette\Database\Connection $database) {
    $this->database = $database;
  }

  public function renderListNews()
  {
    $query = 'SELECT
      '.$this->table.'.'.$this->primary_key.',
      '.$this->table.'.created_when,
      '.$this->table.'.active,
      '.$this->table.'.id_login,
      '.$this->table_desc.'.id_language,
      '.$this->table_desc.'.name,
      '.$this->table_desc.'.description
    FROM '.$this->table.'
    INNER JOIN '.$this->table_desc.' ON
      ('.$this->table.'.'.$this->primary_key.' = '.$this->table_desc.'.'.$this->primary_key.')
    ';
    $res = $this->database->query($query);
    $this->template->posts = $res->fetchAll();

  }

}

nemuze to byt tim Nette\Database\Connection co je v konstruktoru, nebo nejaky use?

Jiz nemam sil, nedokazu se pohnout.

Predem moc dekuji za rady

Jan Endel
Člen | 1016
+
0
-

Proc to děláš tak ošklivě textově a potencionálně nebezpečně?

Jakou chybu ti to hlásí?

David Matějka
Moderator | 6445
+
+1
-

pro pouziti NDBT (tedy table) musis injectnout Nette\Database\Context, nikoliv Connection

thm
Člen | 147
+
+1
-

U presenterů nemusíš používat konstruktor stačí použít anotaci @injectpublic proměnné:

/** @var Nette\Database\Context @inject */
public $context;

Pak už jenom voláš

$this->context->table('news')->where(...)->order(...);

EDIT: opraveno getTable() na table()

Editoval thm (23. 2. 2015 16:35)

lucasso
Člen | 7
+
0
-

vim, ze je takto ten dotaz osklivy, to je take jeden z duvodu, proc se ho chci zbavit.

Nette\Database\Context jsem zmenil, diky za tip, ale jeste to neni uplne tak, jak bych potreboval. Z toho hnusnyho dotazu, co jsem napsal rucne, bych to chtel udelat hezky nejak takto:

$this->database
          ->table('news')
            ->select('id')
            ->select('id_login')
            ->select('created_when')
            ->select('active')
          ->where('id',
          $this->database
                ->table('news_desc')
                  ->select('description')
               );

nicmene u joinovane tabulky news_desc bych chtel vypsat vsechny sloupce, ale takto to hazi hlasku, ze muze obsahovat pouze 1 sloupec. Respektive delam spatne JOIN?

Nenapada Vas, jak to upravim?

Moc diky

lucasso
Člen | 7
+
0
-

thm→ dekuji za bezva radu, urcite jsem tak jiz upravil, konstruktor je pryc, udelal jsem verejnou promennou, nicmene pokud zkusim tvuj priklad, ladenka hlasi :
Call to undefined method SystemContainer::getTable()

urcite je to ale asi cesta

Mysteria
Člen | 797
+
+2
-

Tohle jde?

/** @var \Nette\Database\Context @inject */
public $database

$this->database->table('news');
thm
Člen | 147
+
0
-

Sorry je to samozřejmě $this->database->table('news') a né getTable()

->select() osobně vůbec nepoužívám, nejsem si úplně jistý, ale Nette si samo přijde na to jaké sloupce v tabulce používáš a pak automaticky vyselectuje jenom ty konkrétní, používané.

Spojování tabulek je popsáno hezky v dokumentaci

Editoval thm (23. 2. 2015 16:34)

lucasso
Člen | 7
+
0
-

ano, $this->database->table('news') je OK.

Hezky popsano to je, ale i tak jsem to nepochytil, jak udelat join, jak zadat ze spojovani news.id = news_desc.news_id … nedokazu se tim prokousat, urcite to je jen jednou to ukazat, jen nevim ten system jak

David Matějka
Moderator | 6445
+
0
-

Filozofii NDBT je vybirat data pouze z jedne tabulky, viz hned zacatek v doc:

Nette\Database\Table zjednodušuje a optimalizuje výběr dat z databáze. Hlavní myšlenkou je načítání dat pouze z jedné tabulky a tak, aby se tyto dotazy pokládaly jen jednou.

koukni se na medoty ref a related u active row: https://doc.nette.org/…ase/explorer, ale pokud trvas na vyberu dat jednim dotazem, pouzij join syntaxi, ktera je uvedena u filtrovani, ale necha se aplikovat i pro select

lucasso
Člen | 7
+
0
-

děkuji za rady, vyřešil jsem to tak, že v presenteru mám:

$listNews = $this->content->table('news');
$this->template->posts = $listNews;

a do šablony jsem přes related a foreach přidal relační tabulku.

<tr n:foreach="$posts as $post" >
	<td>{$post->id_news}</td>
    {foreach $post->related('news_desc','news_id')->where('id_language', 1) as $desc}
    	<td>{$desc->name|truncate:30}</td>
        <td>{$desc->description|truncate:90}</td>
    {/foreach}
    <td>{$post->active}</td>
    <td>{$post->created_when|date:'F j, Y'}</td>
    <td><a n:href="News:editNews $post->id_news">upravit</a></td>
</tr>

Sice to funguje, ale nevím, jestli se to takto v nette standardně řeší, proto to ještě přikládám na ukázku, jestli nepíšu blbosti.

může to takto být?

děkuji za koment

thm
Člen | 147
+
0
-

Ano, takto je to dobře. Teda alespoň podle mě. Ještě je možné v databázi pospojovat tabulky přes cizí klíče a ušetřit si tak psaní ještě o název spojovacího sloupce v related, případně využívat takových zápisů jako je např. $post->user->name kde post je ActiveRow, user je název tabulky (která je propojená přes cizí klíč s tabulkou posts) a name je název sloupce u toho šťastného uživatele. Je to zase všechno hezky popsáno v dokumentaci.