Zend Doctrine query innerjoin - doctrine

Great site this is! A lot of good programmers.
But I can't even get a simple doctrine join to work:
$query = Doctrine_Query::create()
->from("StaffIndividualHasAddressAddress sa")
->innerJoin("sa.AddressAddress aa");
Always bums out with:
Message: Unknown relation alias AddressAddress
Is my 'aliassing' not ok? My yaml seems perfectly fine...
And if there is nothing wrong with the query, what else could mess up the process?

you may need to specify the join attribute.
$query = Doctrine_Query::create()
->from("StaffIndividualHasAddressAddress sa")
->innerJoin("sa.AddressAddress aa WITH aa.AdressAdress != ? ",$where);

Related

Laravel, Many-to-many relationships, find() vs where()

I have a Laravel 4.2 site with a pretty simple database layout. The important part is a People model and a Subject model that have a many-to-many relationship. This works, so that, for instance:
$id = 5;
$ppl = Subject::find($id)->people()->orderBy('lastname')->get();
Returns all People for a given Subject. What I'm trying to do is instead of finding all the People for a single subject, to find all the people for multiple subjects. My guess was something like this:
$subjects = array(5, 6, 7);
$ppl = Subject::whereIn('id', $subjects)->people()->orderBy('lastname')->get();
That doesn't work (undefined method people()). Neither does the following (undefined property people):
$ppl = Subject::whereIn('id', $subjects)->people->orderBy('lastname')->get();
I'm currently just using raw SQL t get around this. How can I use eloquent relationships with where() or whereIn() calls on a model? Or, is there just a better eloquent way of approaching this problem.
Edit: Here's the raw SQL I used to get a list of the people.id's for a given array of subjects:
SELECT
DISTINCT(people.id)
FROM people
LEFT JOIN person_subject ON person_subject.person_id=people.id
WHERE
person_subject.subject_id IN (%s) AND
deleted_at IS NULL
Your eloquent relationships should allow you to eagar load the people related to a subject, you can do something like this:
Subject::whereIn('id', $subjects)->with('people')->orderBy('lastname')->get();
This will return your people related to the subjects.
Let me know if this doesn't work.
What you need is to join the tables to order by the lastname:
$ppl = Subject::whereIn('id', $subjects)
->select('subjects.*')
->distinct()
->join('people', 'people.id', '=', 'subjects.people_id')
->orderBy('lastname')
->get();
Check all your tables names because I don't know them and above are just an example one.

Doctrine Where 'IN' operator

This portion of a Doctrine query is only returning results for "validated = 1". How do I modify this query so it will also include results for validated = 3? This is my first "IN".
$query
->andWhere($query->expr()->in('m.validated', ':validated'))
->setParameter('validated', '1,3');
Try this code instead,
$query
->andWhere('m.validated IN (:validated)')
->setParameter('validated', array('1','2'));
Or with the same code giving values in an array.
Hope this helps.
Cheers!

Working with Eloquent, How to select popular comments

I am designer trying to learn coding here and Laravel is so great in that it enables design like me to be able to create something myself smile
On to my question, I followed some of tutorial and now I learn to build simple blog system.
So I have Post model that has relationship $this->morphMany('Like','likeable','likeable_type'); with Like model.
Everything works great so far. Now I want to be able to create 'Popular Posts' page that basically shows the posts ordered by popularity, which is number of likes in my case.
The 'likes' table has these field id | likable_id | likeable_type
'likeable_type', in this case, is 'Post'
'likeable_id' is the post id linked to id in 'posts' table
So in my controller, I tried this.
$popular_ids = DB::table('likes')
->select('likeable_id')
->groupBy('likeable_id')
->orderBy(DB::raw('COUNT(likeable_id)'), 'DESC')
->get();
$popular_posts = Post::whereIn('id',array_pluck($popular_ids,'likeable_id'))->paginate(15);
This gives me all the popular posts but not in the order that I want.
I'm not sure if there is better way to achieve this or it seems that I only miss another 'orderBy' method?
Any suggestion on this?
ps. Sorry for my poor English
SQL IN does not maintain order. To achieve this have to user ORDER BY FIELD('id', , ,...) to achieve this.
$ids = array_pluck($popular_ids,'likeable_id');
$raw = DB::raw('FIELD(id,' + implode(',', $ids) + ')');
$popular_posts = Post::whereIn('id', $ids)->orderBy($raw)->paginate(15);
For more information refer to,
Maintaining order in MySQL "IN" query
I would do this with a join. It's kinda complex but if you want to understand the internals you should read into LEFT JOIN and INNER JOIN. This example is particularly ugly because of the polymorphic relationship.
Post::select('posts.*', DB::raw('COUNT(DISTINCT likes.id) AS popularity'))
->leftJoin('likes', function ($join)
{
$join->on('likes.likeable_id', '=', 'posts.id')
->on('likes.likeable_type', '=', DB::raw("'Post'"));
})
->orderBy('popularity', 'DESC')
->paginate(15);
There is a bonus in that the popularity value is now available on the posts.
$post->popularity;
Thank you Collin for your time! Your answer leads me to the light!!! I modified your answer a bit and finally get what I need. I'm still trying to fully understand it though. This is what I ended up with.
Post::select('posts.*', DB::raw('COUNT(likes.likeable_id) AS popularity'))
->join('likes', function($join)
{
$join->on('likes.likeable_id', '=', 'posts.id')
->on('likes.likeable_type', '=', DB::raw("'Post'"));
})
->groupBy('likes.likeable_id')
->orderBy('popularity', 'DESC')
->paginate(15);
Ps. Even though this code gives me what I want, I'm not sure if I did my db design right.

Doctrine query not executing

trying to execute a Doctrine query that is invariably not happening:
The code I have:
$q = Doctrine_Query::Create()->select('l.lid')->from('lessons l')->where('l.topic =?','Title of topic')
$result = $q->fetchOne() ;
The funny thing is, this returns the wrong column, that is not l.lid but l.someOtherColumn
So not sure where I am goofing up, your comments and critics are much appreciated.
Thanks!
Try to use Create('table_name t ') instead of ->from() ....

Preventing Doctrine's query cache in Symfony

In my Symfony/Doctrine app, I have a query that orders by RANDOM(). I call this same method several times, but it looks like the query's result is being cached.
Here's my relevant code:
$query = $table->createQuery('p')
->select('p.*, RANDOM() as rnd')
->orderBy('rnd')
->limit(1)
->useQueryCache(null)
->useResultCache(null);
$result = $query->fetchOne();
Unfortunately, the same record is returned every time, regardless of me passing null to both useQueryCache and useResultCache. I tried using false instead of null, but that didn't work either. Lastly, I also tried calling both setResultCacheLifeSpan(0) and setResultCacheLifeSpan(-1), but neither call made a difference.
Any insight on how to prevent caching since I want a different random row to be selected each time I call this method?
Edit: I also tried calling clearResultCache(), but that just ended up causing an error stating: "Result Cache driver not initialized".
Edit 2: As requested, here's the SQL generated by calling $query->getSqlQuery():
SELECT c.id AS c__id, c.name AS c__name, c.image_url AS c__image_url,
c.level AS c__level, c.created_at AS c__created_at, c.updated_at
AS c__updated_at, RANDOM() AS c__0 FROM cards c ORDER BY c__0 LIMIT 1
It turns out I'm a moron. I tried to simplify my query for this question, and in doing so, I didn't capture the true cause. I had a where() and andWhere() call, and the combination of conditions resulted in only one possible record being matched. Thanks for taking the time to respond, everyone, sorry to have wasted your time!
Doctrine also caches entities you created in the same request/script run.
For instance:
$order = new Order();
$order->save();
sleep(10); // Edit this record in de DB in another procces.
$q = new Doctrine_Query();
$result = $q->select()
->from('Order o')
->where('o.id = '.$order->id);
$order = $result->getFirst();
print_r($order->toArray());
The print_r will not contain the changes you made during the sleep.
The following code will remove that kind of memory cache:
$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$tables = $connection->getTables();
foreach ( $tables as $table ) {
$table->clear();
}
PS: Added this answer because I found this topic trying to resolve above issue.

Resources