Vypsat username v dalsim modelu?

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

Zdravim mam tady tohle vim ze to je blbe chtel bych to pomoc opravit :

	public function checkUsername()
	{
		$user = $this->userModel->fetchOneBy(['id' => $this->username->getId()]);

		return $this->user->username;
	}
Šaman
Člen | 2666
+
0
-
public function checkUsername()
{
    $user = $this->userModel->fetchOneBy(['id' => $this->username->getId()]);
    return $user->username; // jen $user
}

Jo a od metody checkUsername() bych očekával kontrolu, nikoliv že mi vrátí jméno. Na to je vhodnější název getUsername().
P.S. I ten první řádek je nějaký divný. To opravdu máš property $this->username? Nemá tam být spíš $this->user->id?

Editoval Šaman (19. 12. 2014 0:41)

lukyn94
Člen | 30
+
0
-

Nefunguje to jak si psal

model TestModel.php :

	public function getUsername()
	{
		$user = $this->userModel->fetchOneBy(['id' => $this->user->id]);

		return $user->username;
	}

pro test to vypisu :

{$presenter->testModel->getUsername()}

chyba :

Nette\MemberAccessException

Cannot read an undeclared property App\Model\TestModel::$userModel.
Šaman
Člen | 2666
+
0
-

Tak pak máš chybu už jinde. Předpokládal jsem, že $this->userModel existuje a je to instance nějakého repoziráře. Jestli ne, tak to nesouvisí s Nette, ale s OOP. V tom případě předpokládám, že na tvém kusu kódu je špatně skoro všechno, ale abychom ti mohli poradit, tak musíme vědět:

  1. jak se dostane instance třidy UserModel do property $this->userModel
  2. jestli obsahuje metodu fetchOneBy(), jaké má tato metoda parametry a co vlastně vrací
  3. jestli máš opravdu property $this->username, nebo jestli myslíš $this->user, jak jsem psal

A tohle celé souvisí s Nette jen velmi okrajově, konkrétně v bodě 1, na který můžeš (ale taky nemusíš) použít nette dependency injection container.

lukyn94
Člen | 30
+
0
-

$this->userModel existuje ;) treba v presentru mi to funguje tu ne . jak presne ten injection jak by to vypadalo ?

ali
Člen | 342
+
0
-

To ze ti to funguje v presenteru, neznamena ze ti to bude fungovat v modelu..
https://doc.nette.org/…introduction#…

Do tveho modelu budes muset injectnout userModel sluzbu

/** @var userModel */
private $userModel;

public function __construct(Namespace\Modelu\UserModel $userModel)
{
	$this->userModel = $userModel;
}
Šaman
Člen | 2666
+
0
-

lukyn94 napsal(a):

$this->userModel existuje ;) treba v presentru mi to funguje tu ne . jak presne ten injection jak by to vypadalo ?

Neexistuje, proto: Cannot read an undeclared property App\Model\TestModel::$userModel.

Jestli injectuješ pomocí anotace, nebo inject metody, tak ty jsou taková pomůcka pro presentery, ale v modelu nefungují, tam použij constructor injection, jak píše Ali nademnou.

P.S. Jo houby, undeclared vlastně znamená, že ji vůbec nemáš nadefinovanou, nejen naplněnou. To by ti to psalo že voláš metodu fetchOneBy() on non-object.

Editoval Šaman (19. 12. 2014 18:10)

lukyn94
Člen | 30
+
0
-

On jde model do modelu ?
ja mam testModel a do nej taham z userModel jsem zmatenej jak vubec to ma byt ://

lukyn94
Člen | 30
+
0
-

Nějak jsem to nevyřešil :D

Šaman
Člen | 2666
+
+1
-

Model je třída. UserModel je obyčejná třída, která řeší veškeré operace s Userem. Pokud potřebuje TestModel něco dělat s Userem, potřebuje k tomu UserModel. Ten se mu předá v konstruktoru. Pak teprve můžeš volat $this->userModel->…
Tohle ale opravdu není Nette, ale základy OOP.

Editoval Šaman (20. 12. 2014 4:22)

lukyn94
Člen | 30
+
0
-

jak injectionu model do modelu ?

Šaman
Člen | 2666
+
0
-

Konstruktorem. Potřebuješ samozřejmě, aby UserModel byl v DI kontejneru (tzn. zapsaný v config souboru), ale jestli ti to funguje v presenteru, tak ho tam máš.

lukyn94
Člen | 30
+
0
-

Nevim jestli takhle ?

	/**
	 * @var\Nette\Security\User @inject
	 */
	protected $user;

	/**
	 * @param \Nette\Database\Context $db
	 * @param \Nette\Security\User $user
	 */
	public function __construct(Nette\Database\Context $db, Nette\Security\User $user)
	{
		$this->db = $db;

		$this->user = $user;
	}

	public function getUsername()
	{
		$user = $this->userModel->fetchOneBy(['id' => $user->getIdentity()->getId()]);

		return $user->username;
	}
Etch
Člen | 403
+
0
-

Takhle asi rozhodně ne…

private $user;
private $db;
private $userModel;

public function __construct(Nette\Database\Context $db, Nette\Security\User $user, App\Model\UserModel $userModel){
	list($this->db, $this->user, $this->userModel) = func_get_args();
}

public function getUsername()
{
    $user = $this->userModel->fetchOneBy(['id' => $user->getIdentity()->getId()]);

    return $user->username;
}

EDIT: Ovšem zrovna v tomhle případě stejně nechápu, proč by username neměl být přímo v identitě…

Editoval Etch (20. 12. 2014 14:16)

lukyn94
Člen | 30
+
0
-

proste potrebuji v tomhle modelu ve funkci vratit username a vyuzit ho dal v tom modelu

Marek Šneberger
Člen | 130
+
0
-

V té funkci vrať entitu uživatele. Tu si pak předej kam chceš, resp. si s ní můžeš nakládat jak chceš.

Šaman
Člen | 2666
+
+1
-

lukyn94 napsal(a):

Nevim jestli takhle ?

	/**
	 * @var\Nette\Security\User @inject
	 */
	protected $user;

	/**
	 * @param \Nette\Database\Context $db
	 * @param \Nette\Security\User $user
	 */
	public function __construct(Nette\Database\Context $db, Nette\Security\User $user)
	{
		$this->db = $db;

		$this->user = $user;
	}

	public function getUsername()
	{
		$user = $this->userModel->fetchOneBy(['id' => $user->getIdentity()->getId()]);

		return $user->username;
	}

Já nevím, jestli už trolíš, nebo jsi jen nikdy neslyšel o objektovém programování, nebo co.
Neexistuje proměnná $this->userModel, kterou, nevim proč, chceš používat na prvním řádku metody getUsername. Dokud tu proměnnou nevytvoříš, bude ti vyskakovat chybová hláška o nedeklarované proměnné. Pokud ji vytvoříš, musíš do ní ještě předat UserModel, jinak ti bude prozměnu vyskakovat chyba o volání metody nad non-objektem.

P.S. Tu verzi od Echta bych jen přepsal bez použití fce list() a func_get_args(), prostě si postupně vezmeš všechny parametry konstruktoru a nacpeš je do příslušné property. Je to lépe přehledné.

Editoval Šaman (20. 12. 2014 14:45)

lukyn94
Člen | 30
+
0
-

Kamo ucim se v nette nejsem skill jako ostatni tu proste no :

/**
	 * @var \Nette\Database\Context
	 */
	protected $db;

	protected $userModel;

	/**
	 * @var  string
	 */
	protected $user;

	/**
	 * @param \Nette\Database\Context $db
	 * @param $user
	 * @param $userModel
	 */
	public function __construct(\Nette\Database\Context $db,
							    \Nette\Security\User $user,
			                    \App\Model\UserModel $userModel)
	{
		list($this->db, $this->user, $this->userModel) = func_get_args();

		$this->db = $db;
		$this->user = $user;
		$this->userModel = $userModel;
	}

	/**
	 * Get username lower
	 *
	 * @return string
	 */
	public function getUsername()
	{
		$this->user = $this->userModel->fetchOneBy(['id' => $this->user->getIdentity()->getId()]);

		$username = Nette\Utils\Strings::lower($this->user->username);

		return $username;
	}

Kdyby to nekdo vedel jak lepe udelat nebo opravit ,prijmu i hejt ;)

Editoval lukyn94 (20. 12. 2014 14:54)

Etch
Člen | 403
+
+1
-

Tady nejde o to, jestli se zrovna učíš s nette a jakej seš „skill“. Tady jde o to, že nemáš základní znalosti OOP. Tvůj problém nemá nic společného s nette.

Poslední kód co si zde uvedl, je zase poněkud úlet, protože si v konstruktoru vyžádáš Nette\Security\User, předáš jí do „$this->user“ (ač v DOCu uvádíš, že ta proměnná má být string) a následně do ní po zavolání getUsername() naférovku nacpeš string, což minimálně zavání. Když už, tak by to mělo vypadat například následovně:

/**
     * @var \Nette\Database\Context
     */
    protected $db;

    protected $userModel;

    /**
     * @var  \Nette\Security\User
     */
    protected $user;

    /**
     * @param \Nette\Database\Context $db
     * @param $user
     * @param $userModel
     */
    public function __construct(\Nette\Database\Context $db,
                                \Nette\Security\User $user,
                                \App\Model\UserModel $userModel)
    {

        $this->db = $db;
        $this->user = $user;
        $this->userModel = $userModel;
    }

    /**
     * Get username lower
     *
     * @return string
     */
    public function getUsername(){
        $user = $this->userModel->fetchOneBy(['id' => $this->user->getIdentity()->getId()]);
        $username = Nette\Utils\Strings::lower($user->username);

        return $username;
    }

a opět se vnucuje myšlenka, proč username není přímo v identitě, protože když už si jednou toho uživatele „vytváříš“, tak je rozumné mu běžně používané věci (jako například username) dát do identity. Ohledně toho konstruktoru buď použij

$this->db = $db;
$this->user = $user;
$this->userModel = $userModel;

nebo

list($this->db, $this->user, $this->userModel) = func_get_args();

v tomto konkrétním případě je to ekvivalentní zápis. Ovšem vzhledem k tomu, že pravděpodobně nevíš, co tak kombinace list() a func_get_args() vlastně dělá bych ti doporučil používat spíše ten druhý zápis. Oba zápisy najednou nemá smysl používat, protože jsou ekvivalentní a jeden je tedy navíc.

Editoval Etch (20. 12. 2014 16:08)

Mysteria
Člen | 797
+
0
-

Jenže u tebe není problém s Nette ale v tom, že neznáš základy OOP.
Protected proměnný jsou zde k ničemu, pokud od toho nebude dědit.

Tyhle dvě věci jsou ekvivalentní (oboje dělá to samé):

list($this->db, $this->user, $this->userModel) = func_get_args();

$this->db = $db;
$this->user = $user;
$this->userModel = $userModel;

Tohle je totiž problém, jako kdyby jsi chtěl počítat rovnice, ale neuměl sčítat a odčítat ⇒ prostě nemůžeš dělat složitelnější věci, když nemáš základy.

EDIT: @Etch: Byls rychlejší… ;)

Editoval Mysteria (20. 12. 2014 16:03)

lukyn94
Člen | 30
+
0
-

Dekuji vsem za pomoc ted vim zase o neco vic ;)