Issue with "where" in an associated query in Symfony 3 - php

I'm trying to make a "search engine" for my app; the table I want to show, contains two fields which are associated to another tables.
I'm using this query:
Select work from WorkBundle:Work work
where work.client.name like '$search%'
Work, is associated with the tables "user" and "client", I have the associations correctly defined so I don't have to use the inner join statement, but I get the following error:
[Semantical Error] line 0, col 68 near 'nombre like 'fsdf%'': Error: Class WorkBundle\Entity\Work has no field or association named client.nombre
I don't know how to access to the "name" field which is on the "client" table.
Actually I can do the same by using a full inner join query and it works but I can't use it in my app.

I do not know for sure but it seems you cant use selectors like work.client.name. I think it based on doctrine uses "lazy" queries. So you must use table joins in this case.
So it should look smth like that
// work repository
public function findByKeyword($keyword)
{
$qb = $this->createQueryBuilder("w");
$result = $qb
->add('where', $qb->expr()->like("wc.name", ':keyword'))
->leftjoin("w.client", "wc") //or join or innerjoin depends of your case
->setParameters([
'keyword' => $keyword
])
->getQuery()
->getResult()
;
return $result;
}

Related

SQL select show table if not same value from another table (Laravel)

This is my query, I tried this query it works.
SELECT *
FROM conference_venue
WHERE id_venue NOT IN (SELECT id_venue FROM submission_data WHERE id_submission = 1);
i want to display data in conference_venue. but I don't want to display data whose id_venue is the same as the submission_data table (same as id_venue whose id_submission is mentioned).
I'm trying to make a query for the laravel version, but it's a blank white screen with no errors.
DB::table('conference_venue')
->whereNotIn('id_venue', function($q){
$q->select('id_venue')
->from('submission_data')
->where('id_submission', '=', 1);
})->select('*')->get();
This query works when I try it in sql query console but fails when I try it with Laravel query builder.
You can try this:
DB::table('conference_venue')
->select('*')
->whereRaw(
'conference_venue.id_venue NOT IN (SELECT submission_data.id_venue FROM submission_data WHERE id_submission = 1)'
);
Or better yet, create a Model for conference_venue and submission_data (ie: ConferenceVenue, SubmissionData) and you can add Eloquent relationships for ConferenceVenue and SubmissionData.
Eloquent relationships, which supports a variety of common
relationships (One To One, One To Many, Many To Many, etc.), are
defined as methods on your Eloquent model classes. Since relationships
also serve as powerful query builders, defining relationships as
methods provides powerful method chaining and querying capabilities.
Eloquent: Relationships
On you ConferenceVenue Class, you can add a method something similar to the following:
public function available() {
return this->hasMany(SubmissionData, 'id_venue')
->select('*') // You can also specify relevant columns ONLY
->whereRaw(
'conference_venue.id_venue NOT IN (SELECT submission_data.id_venue FROM submission_data WHERE id_submission = 1)'
);
}
Where you can use the relationship method as follows:
$available = ConferenceVenue::with('available')->get();

Bitwise and condition in a Laravel relation (Eloquent ORM)

I am trying to create a specialized relation on a user (Model) to the group model. In the schema I am working with, the groups have a type attribute that is a bitmask, where each bit defines a certain characteristic for a group.
For example, we might have a group:
name: New York
type: 33554436 (1<<25 | 1<<24)
With plain SQL, I can get the groups of interest in with the query:
select g.* from foobar_group g where (type & 1<<25) != 0
I wish to define this relation in the user model for convenience and what have is:
<?php
class UserModel extends Illuminate\Database\Eloquent\Model
{
public function visitedCities()
{
return $this->belongsToMany(
GroupModel::class,
'foobar_group_member',
'user_id',
'group_id')
->with([ 'type' => function ($belongsToMany) {
$belongsToMany->where('type', '&',
GroupModel::CITY_TYPE,
GroupModel::CITY_TYPE)
}])
;
}
}
In essence, I am trying to add the where condition from the SQL query above to the join statement (relation). Do you know how to do that? Do I need to extend the Eloquent\Relation class?
You can use whereRawto execute raw where clauses.
Eloquent doesn't support more fancy where clauses than like or = and the standard stuff. I suggest you take a look at the documentation
I your case you probably want to use the something like:
$belongsToMany->whereRaw('(type & 1<<25) != 0')
and add it to your select clause.
If you want to debug your SQL you can use:
DB::enableQueryLog();
//Execute Eloquent select
dd(DB::getQueryLog());
That way you can also see that if you put anything like bitmasks into the middlepart of the where clause it gets replaced with =

Getting entity which has some elements

I have a Book entity which has a One2Many relationship with the Page entity. I wanted to create a query which retrieved all the books which had at least one page. I did:
$qb = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Book')
->createQueryBuilder('b');
->leftJoin('b.pages','p')
->having($qb->expr()->gt($qb->expr()->count('p'), 0));
$books = $qb
->getQuery()
->getResult();
The problem is that, although there are many books which have pages, this query only returns a single book.
The query created is:
SELECT b FROM Acme\DemoBundle\Entity\Book b LEFT JOIN b.pages p HAVING COUNT(p) > 0
which looks fine to me. Any idea what may be wrong?
It is simpler to use
->innerJoin('b.pages','p')
instead of
->leftJoin('b.pages','p')
you don't need aggregate function. In short: this innerjoin will return only Books that can be joined with at least one Page.
You should add groupBy as you are using aggregate function. e.g.
$qb = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Book')
->createQueryBuilder('b');
->leftJoin('b.pages','p')
->groupBy('b.id')
->having($qb->expr()->gt($qb->expr()->count('p'), 0));

Symfony2 - Custom Query in Entity Repo doesn't seem to return expected results

So I came to a point where I needed to create a custom query in my Entity Repository to do a sub-select.
The query itself seems sound and does indeed find the result I am after (I checked by running the query in Navicat) however, when trying to view the results (using Twig templates) I am getting the following error:
Item "id" for "Array" does not exist in DEMODemoBundle:Staff/Company:company.html.twig at line 42
Line 42 in that template is:
<td>{{ entity.id }}</td>
Previously, I was using a basic "findAll" query in my controller, and the Twig template worked fine (it uses a for loop to go through the results and print out a table)
So, I was under the assumption that if my custom query fetched a list of results, with all the same columns (just 1 added extra in the sub-select, not the ID mentioned though) then everything should be fine!
But clearly not. It seems as though there is another Array level for some reason and I am unsure as to why?
Here is my custom query in the repo (it does a sub select to create a parent_name column):
public function getCompanyWithParent()
{
$dql = 'SELECT c, (SELECT p.name FROM DEMO\DemoBundle\Entity\User\Company p WHERE p.id = c.parent) as parent_name FROM DEMO\DemoBundle\Entity\User\Company c';
$query = $this->getEntityManager()->createQuery($dql);
return $query->getArrayResult();
}
I have tried both:
return $query->getArrayResult();
and
return $query->getResult();
But to no avail.
Any ideas folks?
Sorted it. Seems I had to specify the columns I wanted to pull through e.g. SELECT c.id, c.name ..., and sadly couldn't just use SELECT c, ... FROM ...

Accessing Doctrine related field from JOIN

I am attempting to pull a list of users using doctrine, with a join, from my database. I have the following function in my model:
public function getAttendees() {
$q = Doctrine_Query::create()
->select('a.id, a.name, a.url, m.id')
->from('Attendees a')
->leftJoin('a.Meetings m WITH m.Meeting_Slot_ID = ?', $this->getId());
return $q->execute();
}
I've checked the SQL generated by this query, and it is gabbing all the data I want. I am now trying to access the data retrieved. I have the following working:
foreach($object0>getAttendees() as $attendee){
echo $attendee->getName();
}
However, I can't figure out how to access the m.id field.
I think you can do this:
$attendee->getMeetings()->getId()
You have to use the alias you defined in your schema.yml (if you are using symfony)
Generally Doctrine uses this way to chain related models together:
model1->model2->model3
...->getModel2()->getModel3()->getModel3Field()
$attendee->getMeeting()->getId(); OR soemthing to that effect depending on how you have your relations/properties named.

Categories