Assistance with Doctrine ODM query - doctrine

I have the following query which is providing undesired results.
$query = $dm->createQueryBuilder('MainClassifiedBundle:Discussion')
->field('id')->equals($discussionId)
->field('discussion_id')->equals($discussionId);
What I am trying to do is to find any documents where id = $discussionId OR discussion_id =$discussionId.
Many thanks for your help

Well, you have the methods add() and addOr of query builder:
$query = $dm->createQueryBuilder('MainClassifiedBundle:Discussion');
->add($query->field('id')->equals($discussionId))
->addOr($query->field('discussion_id')->equals($discussionId));
Also you can replace the add and addOr methods by where and orWhere

Related

Method Illuminate\Database\Eloquent\Collection::orderby does not exist

$posts = Post::all()->orderby('created_at','desc')->where('usr_id','=',session('LoggedUser'))->get();
return view('admin.profile',compact('userInfo' , 'posts'));
i am making a custom auth for a journal activity but i cant sort the content i shows this error
"Method Illuminate\Database\Eloquent\Collection::orderby does not exist. "
$posts = Post::where('usr_id','=',session('LoggedUser'))->orderby('created_at','desc')->get();
True query like that. When you take all() already query done.
Change it to:
$posts = Post::where('usr_id','=',session('LoggedUser'))->orderby('created_at','desc')->get();
you cant use all() and orderBy because all() does not allow the modification of the query.
I believe this might be because you typed orderby instead of orderBy (notice the uppercase). See laravel orderBy documentation if needed.
Plus, as mentionned by other, don't use all() if you need to do other thing (where clause, order by, etc) in you query.
Change the orderby to orderBy. This could be the reason you are getting the error.
$posts = Post::all()->orderBy('created_at', 'DESC')->where('usr_id','=',session('LoggedUser'))->get();
return view('admin.profile',compact('userInfo' , 'posts'));
Or...
If you want to get specific number of posts you can do it this way to avoid using the Post::all
$posts = Post::orderBy('created_at', 'DESC')->where('usr_id','=',session('LoggedUser'))->paginate(5);
return view('admin.profile',compact('userInfo' , 'posts'));
Yeah this is pretty confusing and just got me as well.
The actual problem isn't the capitilization typo (orderby versus orderBy) but rather the fact that you're using ->all() instead of just Model::orderBy()->...
The moment you use ->all() the object is transformed to another type of collection object and the normal methods one would expect do not exist.
In this case you should rather use sortBy().
See here.

when to use get() in query laravel 5

I have a basic query set up in the show method of a laravel resource
public function show($id){
$results = Student::find($id);
$drives= Drive:: where('student_id', $id);
}
The query for $results works perfectly. The query for $drives does not work unless I do ->get() at the end of it. Why is this? what's the difference between the two queries so that one requires the ->get() and the other does not? Solving this problem took me like 5 hrs and i'm just curious as to the functionality behind it so i can avoid this headache in the future.
Some eloquent expressions have a get implicitly. Those ones who are made by a Query Builder will need a ->get() call, find(), findOne()... won't need a get().
https://laravel.com/docs/5.6/eloquent#retrieving-models
https://laravel.com/docs/5.6/queries
use get to execute a builder query. unless you run the get() query wont be executed. get will return a collection.
1 - Use query builder to build queries however you want.
$drives= Drive:: where('student_id', $id);
dd($drives); // will return a query builder, you can use it to build query by chaining
2 - when you are ready to execute the query call get()
$drives= Drive:: where('student_id', $id);
$result = $drives->get()
dd($result); // will return a database query result set as a collection object
If you want to get a single object by id use find, to get a single object
$results = Student::find($id);
dd($result); will return a single model
Using the function find() on a model gets a query result based on the primary key of the model, id in this case.
When using where(), it gets a collection (an object of all query results), so if you only want the first result you must call $drives=Drive::where('student_id', $id)->first();
Here is a more in-depth explanation: the difference of find and get in Eloquent

How can I write this query using the laravel query builder?

I'm on laravel 5.1 using postgres as the DB. I have a fiddle here in case it helps understand my issue: https://www.db-fiddle.com/f/5ELU6xinJrXiQJ6u6VH5/4
with properties as (
select
properties.*,
json_agg(property_fields.*) as property_fields
from
properties
left join fields as property_fields
on property_fields.parent = 'property' and property_fields.parent_id = properties.id
group by properties.id, properties.deal_id, properties.address
)
select
deals.*,
json_agg(properties.*) as deal_properties,
json_agg(deal_fields.*) as deal_fields
from deals
left join properties on deals.id = properties.deal_id
left join fields deal_fields on deal_fields.parent = 'deal' and deal_fields.parent_id = deals.id
group by deals.id, deals.name
order by deals.id
Writing most of this is fairly straight forward. The problem I'm having is with the with properties as (...) block. I've tried something like:
DB::statement('WITH properties AS ( ... )')
->table('deals')
->select(' deals.*, json_agg(properties.*) as deal_properties, ')
...
->get();
But I notice the execution stop after DB::statement()
Is there a method in the Query Builder that I'm missing? How can I prefix my query with the WITH properties AS (...) statement?
I think it should also be noted that I'm trying to implement a Repository Pattern and I can't just wrap a DB::statement() around the whole query.
I've created a package for common table expressions: https://github.com/staudenmeir/laravel-cte
$query = 'select properties.*, [...]';
DB::table('deals')
->withExpression('properties', $query)
->leftJoin([...])
->[...]
You can also provide a query builder instance:
$query = DB::table('properties')
->select('properties.*', [...])
->leftJoin([...])
->[...]
DB::table('deals')
->withExpression('properties', $query)
->leftJoin([...])
->[...]
if you want some data fetch from a table you can use this type of code
$user = DB::table('table name')->where('name', 'John')->where('height','!>',"7")->select('table fields which you want to fetch')->get();
Or try using the larevel Eloquent ORM which will make things easier with the database.
for more example or reference
https://laravel.com/docs/5.0/queries
I think you can actually do this with eager loading,
assuming that the relationships are set up correctly.
(More reading here: https://laravel.com/docs/5.4/eloquent-relationships#constraining-eager-loads)
So I think you'd be able to add something like
->with(['properties' => function ($query) {
$query->select('field')
->leftJoin('join statement')
->groupBy('field1', 'field2');
}])

Where Is My Raw Query?

Here is my controller code;
$temp_table_data = $temp_table
->setTempTable($generated_temp_table)
->newQuery()
->with(['payment' => function ($query) use ($column_values) {
$query->select($column_values);
}])->get();
My toSql query is right below it;
$sql = str_replace(['%', '?'], ['%%', "'%s'"], $temp_table->toSql());
$fullSql = vsprintf($sql, $temp_table->getBindings());
print_r($fullSql);
My code prints out;
select * from `selected_postcodes_1434968225_1`
Where are the details of the payments information that I am "with"ing? If I want to print out the raw query now, to show another developer, to get some help, what am I supposed to do here?
The eager loaded relationships are fetched in a separate query. You can use DB::getQueryLog() to get all run queries. Note that you have to enable it first using with DB::enableQueryLog().
Another alternative is the Laravel Debugbar package that shows you all queries and much more.

Group By Eloquent ORM

I was searching for making a GROUP BY name Eloquent ORM docs but I haven't find anything, neither on google.
Does anyone know if it's possible ? or should I use query builder ?
Eloquent uses the query builder internally, so you can do:
$users = User::orderBy('name', 'desc')
->groupBy('count')
->having('count', '>', 100)
->get();
Laravel 5
WARNING: As #Usama stated in comments section, this groups by AFTER fetching data from the database. The grouping is not done by the database server.
I wouldn't recommend this solution for large data set.
This is working for me (i use laravel 5.6).
$collection = MyModel::all()->groupBy('column');
If you want to convert the collection to plain php array, you can use toArray()
$array = MyModel::all()->groupBy('column')->toArray();
try: ->unique('column')
example:
$users = User::get()->unique('column');

Resources