Doctrine 2 – zlozitejsia asociacia

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

Ahojte,

mam Entitu User

	/**
* @ORM\OneToMany(targetEntity="UserEmail", mappedBy="user", orphanRemoval=true, cascade={"persist"})
*/
	protected $userEmails;


	/**
* @ORM\OneToMany(targetEntity="UserNotification", mappedBy="user", orphanRemoval=true, cascade={"persist"})
*/
	protected $notifications;

ktora je vlastnikom tychto dvoch asociovanych:

UserEmail: obsahuje zoznam emailovych adries uzivatela

/**
	 * @ORM\ManyToOne(targetEntity="User", inversedBy="userEmails")
	 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
	 */
	protected $user;

	/** @ORM\Column(type="string", length=100, nullable=false, unique=true) */
	protected $email;

UserNotification: obsahuje zoznam uzivatelom povolenych notifikacii

	/**
	 * @ORM\ManyToOne(targetEntity="User", inversedBy="notifications")
	 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
	 */
	protected $user;

	/** @ORM\Column(type="integer", length=3) */
	protected $notification_type;

	/**
	 * @ORM\OneToOne(targetEntity="UserEmail")
	 * @ORM\JoinColumn(name="email_id", referencedColumnName="id")
	 */
	protected $email;

A potrebujem zistit ci ma uzivatel povolene zasielat notifikaciu dajme tomu typu 1.

$email = $this->userNotificationDao->findOneBy(['user' => $user, 'notification_type' => 1]);
// ak existuje tak v tomto pripade mam adresu v $email->email->email;

len problem nastava, ak sa omylom dostane ID hodnota emailu ineho uzivatela do pola email_id (userNotification), tak vrati chybny email.

Kedze posledny dotaz ktory prebehne (predpokladam):
FROM user_email t0
WHERE t0.id = 24

a bezpecnejsie by bolo keby tam bola este podmienka AND user_id = ?

da sa nieco take urobit na urovni asociacie entit, alebo si to musim vyriesit v kode sam?

amik
Člen | 118
+
0
-

Tak především máš nadbytečnou asociaci mezi notification a user. Jelikož notification je asociována s e-mailem, který je asociován vždy jen s jedním s uživatelem, dá se uživatel odvodit z asociace notification->email->user. Pak sice nevybereš asociaci podle uživatele přes findOneBy, budeš si muset napsat DQL, ale nebudeš mít redundantní vazby.

DQL bude něco jako

$entityManager->createQuery("SELECT n FROM UserNotification n JOIN n.email e WHERE e.user = :user")
->setParameter('user', $user)
->getSingleResult();

Doctrine se o všechny asociace na úrovni SQL postará správně. Kdyby\Doctrine ti rovnou integruje panel, kde vidíš všechny proběhlé dotazy přeložené do SQL, doporučuji používat raději než věštit z koule, co se na úrovni SQL děje :)

marioff
Člen | 69
+
0
-

v buducnosti planujem aj notifikaciu pomocou telefonu (pripadne aj inym sposobom), teda vznikne dalsia entita napr. UserPhone ..

a plan bol ze notifikacie bude mat na starosti Listener, ktory bude pocuvat na urcite udalosti. ak nastane, vyziada si od Repository kontaktne udaje uzivatela na zakladne typu notifikacie (zmena hesla, zmena loginu, atd – na kazdy typ si moze uzivatel zvolit iny kontakt). A ten mu teda vrati napr. emailovu adresu a phone NULL, resp. naopak, alebo dokonca dostane oba kontaktne udaje, ci ziadne.

Cize v Entite UserNotification tym padom potrebujem mat user_id aby som si to vedel najst. Islo mi o to, ak sa nejakym sposobom (kompromitacia DB) dostane nespravne ID emailu, ktory ma odlisny uzivatel, tak aby nevratilo tento neplatny email, teda neodoslalo notifikaciu tam kde nema.