Proč se musí psát ->ref()?
- tomaass
- Člen | 74
Ahoj,
mám v DB tabulky a nedaří se mi je propojit tím hezkým způsobem
$row->tabulka_jina->polozka
Ale když použiji druhý (otřesný) způsob
$row->ref('package','barcode')->quantity
tak to jde.
Jenže já chci psát ten první a už jen proto že je to hezčí, ale i proto, že to bude v šabloně.
Jinak v DB (Postgre) mam krásné primární klíče i cizí a je to k ničemu, protože to píše:
PDOException
No reference found for $movement->package
Data tam také jsou, a je to vazba N:1. Nebo-li: pro každý z N řádků najdeme přávě 1 záznam v druhé tabulce.
Jak docílím prvního zápisu aby to fungovalo? Děkuji za rady
- tomaass
- Člen | 74
ok. Chci propojit tabulky movement->package
kód:
V Modelu:
$data =
$this->connection->table('movement')
->where(
array(
'date'=>$inventorying->checkdate,
'action_id'=>Action::INVENTURA))
->order('id');
Kód v šabloně:
{if count($history)}
{foreach $history as $row}{dump $row}
<div class="badge info">
<i class="icon-barcode icon-white"></i> {$row->barcode|BarCode} |
Součet: <span style="color:red;">{$row->ref('package','barcode')->quantity}</span><span class="muted">/{$row->package->packagequantity}</span>
{if $row->quantity}
<span class="pull-right">
{if $row->quantity > 0}+{/if}{$row->quantity}
</span>
{/if}
</div>
{/foreach}
{else}
Není co zobrazit.
{/if}
Tabulky:
CREATE TABLE "package"
(
component_id integer NOT NULL,
id integer NOT NULL,
packagequantity integer NOT NULL,
quantity integer NOT NULL,
checkdate timestamp without time zone,
location_id integer,
status_id integer,
note text,
company_id integer,
supliercode text,
price real,
barcode integer NOT NULL,
CONSTRAINT "PK_package" PRIMARY KEY (barcode),
CONSTRAINT "FK_company_id" FOREIGN KEY (company_id)
REFERENCES company (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_component_id" FOREIGN KEY (component_id)
REFERENCES component (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_location_id" FOREIGN KEY (location_id)
REFERENCES location (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_status_id" FOREIGN KEY (status_id)
REFERENCES status (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT package_barcode_key UNIQUE (barcode)
)
WITH (
OIDS=FALSE
);
ALTER TABLE "package"
OWNER TO postgres;
CREATE TABLE movement
(
id serial NOT NULL,
package_id integer NOT NULL,
component_id integer NOT NULL,
date timestamp without time zone NOT NULL DEFAULT now(),
quantity real NOT NULL,
shipment_id integer,
user_id integer NOT NULL,
action_id integer,
location_id integer,
barcode integer,
CONSTRAINT "PK_movement" PRIMARY KEY (id),
CONSTRAINT "FK_action_id" FOREIGN KEY (action_id)
REFERENCES action (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_location_id" FOREIGN KEY (location_id)
REFERENCES location (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_package_id" FOREIGN KEY (barcode)
REFERENCES "package" (barcode) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_shipment_id" FOREIGN KEY (shipment_id)
REFERENCES shipment (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_user_id" FOREIGN KEY (user_id)
REFERENCES "user" (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "UQ_movement_id" UNIQUE (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE movement
OWNER TO postgres;
Jake jsou dalsi podminky pro ten reflection?
- vvoody
- Člen | 910
Tvoj FK neodkazuje na PK tabulky package, takže by ani ref nemalo fungovat, teda fungovať bude ale, myslím že teraz sa matchuje
movement.barcode = package.id
namiesto toho čo očakávaš ty
movement.package = package.barcode
Nette Database vždy čaká že sa odkazuje na PK. Pozri sa do debug baru aké sqlka to vykonáva, či sa náhodou nemýlim.
K tomu správnemu zápisu bez funkcie ref, to pri Discovered Reflection konvencia nieje ako si písal:
$row->tabulka_jina->polozka
Správne to je takto:
$row->cast_nazvu_FK->polozka
Pozri si príklad s knihami a autormi. Často sa stáva že v jednej tabulke (book) sú dva FK (author_id,maintainer_id) ktoré odkazujú na tú istú tabulku, preto by sme si v tomto prípade nevystačili s konvenciou:
$row->tabulka_jina->polozka
Ak by sme v tom príklade premenovali tabulku authors na users, tak by stále korektne fungoval zápis:
$book->author->name;
$book->maintainer->name;
Takže ak použiješ časť názvu FK (barcod,barco,barc…)
$movement->barcod->polozka
Áno, je to logický nezmysel pristupovať k $movement->barc a podobným nezmyselným properties, preto treba dodržovať konvencie vytvárania názvov FK, čiže u teba by som premenoval movement.barcode na movement.package_barcode. V takomto prípade už ti bude fungovať práve to čo si asi pôvodne chcel:
$movement->package->polozka
Ale skorej si skontroluj to, čo som písal na začiatku tohto postu, že s ktorým stĺpcom z package sa matchuje FK z tabulky movement.
- tomaass
- Člen | 74
Děkuji.
Bohužel, PK tabulky package je opravdu ‚barcode‘ a v movementu je FK namireny na package.barcode.
Zkousel jsem zapsat
$row->FK_package_id->quantity
vysledkem je opet:
No reference found for $movement->FK_package_id
Kde se dájí najít ty informace, co jsi mi tu předal? O těch FK? To demo jsem pročítal ale nic takovýho jsem tam nenašel…
- vvoody
- Člen | 910
Nehovoril som o Constraints ale priamo o názve stĺpca v ktorom je FK. Informácie o tom získaš asi len tak že si prejdeš zdrojáky tej reflection. Pozrel si sa na tie sqlka ktoré to vykonáva ak použiješ metódu ref?
edit: aha pardon, takže barcode je PK :) ked som videl id tak som automaticky predpokladal že práve ono je PK. Tak potom navrhujem premenovanie toho FK (názvu stĺpca) na package_barcode a potom vyskúšať
$movement->package->quantity
alebo zmena štruktúry neprichádza do úvahy?
Editoval vvoody (8. 11. 2012 19:47)
- tomaass
- Člen | 74
tak a teď to funguje. Děkuji Vám.
A ještě mi prosím napovězte.
vyřešilo to přejmenování toho sloupce na „package_barcode“ jak jste navrhoval.
Když se ten sloupec jmenoval jen barcode, tak to nefungovalo
($row->barcode->quantity)
ale po přejmenování na „package_barcode“ to jde, když volám
$row->package->quantity.
Jakto? Používá se snad část názvu FK na název rabulky nebo co?
- vvoody
- Člen | 910
Ano, ako som písal, pre referencie na iné tabuľky sa používa časť názvu FK. Určite nie jeho celý názov, lebo tým len získame hodnotu daného Fk/stĺpca (to dôvod tej chyby Trying to get property of non-object).
Je to proste, dovolím si tvrdiť, široko zaužívané pravidlo nazývať FK názvom odkazovanej tabulky s pripojením postfixu _id. V tvojom prípade más PK namiesto id na stĺpci barcode, preto postfix _barcode čo zafunguje tak isto dobre. Discovered reflection proste s takýmito konvenciami počíta.