|
PHP PHP aplikacije, Smarty, PEAR |
|
Alati teme | Način prikaza |
26. 11. 2013. | #1 |
Ivan Dilber
Sir Write-a-Lot
|
Laravel4 - Eloquent Many to Many relacija
Imam 2 Eloquent modela: Product i Tag koji su u many to many relaciji:
Kôd:
class Product extends Eloquent { //... public function tags() { $this->belongsToMany('Tag'); } } class Tag extends Eloquent { //... public function products() { $this->belongsToMany('Product'); } } Ja sam nesto zbudzio sa 2 for petlje, ali je to potpuno neefikasno u poredjenju sa obicnim sql-om, pa me zanima koji bi bio pravilni, skolski nacin da se takav upit uradi preko ORM-a koristeci ugradjene relacije?
__________________
Leadership is the art of getting people to want to do what you know must be done. Poslednja izmena od ivanhoe : 26. 11. 2013. u 07:43. |
26. 11. 2013. | #2 |
Nekad bio ddz
Expert
|
U takvom trenutku ja obično opsujem framework, a onda u repository klasi kreiram metod koji sadrži sirovi SQL upit.
__________________
Converting dead links into hyperlinks since 1996. |
26. 11. 2013. | #3 |
VD IT Direktora
Invented the damn thing
Datum učlanjenja: 08.06.2005
Lokacija: Beograd
Poruke: 2.118
Hvala: 503
1.307 "Hvala" u 282 poruka
|
Nemam iskustva sa tim ORM-om, ali ako je u pitanju yet another ActiveRecord clone (na šta mi na prvi pogled liči, ali možda se varam), evo kako bi se to rešilo tamo:
has_many metoda omogućava da se zada "posredna relacija" pomoću opcije "through", tako da možeš da deklarišeš novi scope na ovu foru: Kôd:
class Tag < ActiveRecord::Base has_and_belongs_to_many :products end class Product < ActiveRecord::Base has_and_belongs_to_many :tags has_many :related_products, :through => :tags, :source => :products end Kôd:
Product.find_by_name('semalirana pufna za frezenkovanje').related_products
__________________
blog Poslednja izmena od jablan : 26. 11. 2013. u 11:07. |
26. 11. 2013. | #4 |
Ivan Dilber
Sir Write-a-Lot
|
@jablan: Tako nesto sam uradio:
Kôd:
$related = array(); foreach ($product->tags as $tag) { foreach($tag->products()->where('id', '!=', $id)->get() as $p) { $related[ $p->id ] = $p; } } Bilo bi super kad bih umesto petlje mogao da iskoristim whereIn() tj. da koristim IN sql operator, ali ORM ne ume sa tim da se snadje (ili ja ne znam da formulisem kako treba)...
__________________
Leadership is the art of getting people to want to do what you know must be done. Poslednja izmena od ivanhoe : 26. 11. 2013. u 17:47. |
26. 11. 2013. | #5 |
VD IT Direktora
Invented the damn thing
Datum učlanjenja: 08.06.2005
Lokacija: Beograd
Poruke: 2.118
Hvala: 503
1.307 "Hvala" u 282 poruka
|
Ne, ne, ovo što sam ja napisao u Railsu (AR) automatski pravi SQL joinove, nema potrebe za petljama. Gledao sam malo dokumentaciju za Laravel, nema baš to isto, ali pogledaj pod "eager load".
__________________
blog |
26. 11. 2013. | #6 |
Ivan Dilber
Sir Write-a-Lot
|
Eager load je malo drugacija stvar, napravi odvojen upit i pokupi sve podatke koji su u relaciji, ne pravi join.
Ja sam ovo resio ovako jer mislim da ne postoji automatski nacin da se pretrazi po pivot tabeli (a bilo bi logicno da ima): Kôd:
$tag_ids = $product->tags()->lists('id'); $related = Product::join('product_tag', 'products.id', '=', 'product_id')->where('id', '!=', $id)->whereIn('tag_id', $tag_ids)->get();
__________________
Leadership is the art of getting people to want to do what you know must be done. |
01. 12. 2013. | #7 |
Mladen Milentijevic
Professional
Datum učlanjenja: 20.06.2007
Lokacija: Sweden
Poruke: 224
Hvala: 43
21 "Hvala" u 21 poruka
|
Ovako nekako bez pivot table
Kôd:
/** * Get all products with a tag * * @param string $tag * @return array */ public function productsByTag($tag) { return Products::with('tags') ->select('products.*') ->join('tags', 'products.id', '=', 'tags.product_id') ->where('tags.tag', '=', $tag); } |
|
|