Lumen/Laravel raw postgis query - laravel-5

I want to make little service with json output in Lumen.
When I run raw postgis query
$parcells = DB::table('parcells')
->select(DB::raw('ST_AsGeoJSON(wkb_geometry)::json as geometry, nr' ))
->where('nr', '=', $id)
->orderBy('id', 'asc')
->get();
json_encode($parcells)
I get array of objects with geometry attribute which contain string (its need to be parsed to be valid json object).
Is there way to get those values as json object?

You should probably consider using row_to_json() function.
For more info pls see here and here

Related

Manual function inside query?

Is there any way to put a manual function inside a query in Laravel.
I've timestamp saved in string in DB. I want to convert timestamp from one timezone to another. All the timestamp is inserted in one time zone, and depending upon my user I fetch the timestamp and convert it into their timezone.
what I want to achieve is something like this..
$query = BlogCategory::select('merchant_id', userTime(added_at))
->where('site_id', $site_id)
->get();
userTime() function takes two parameter, the timestamp and the timezone and converts the timsestamp to time of the user.
I want to use userTime() function before fetching the data. I dont want to fetch the data first and then do foreach and so on.
I know I might be absolutely absurd but is there anything of this sort in Laravel?
Well you can achieved that using collection map
$query = BlogCategory::select('merchant_id', 'added_at')
->where('site_id', $site_id)
->get();
$dateAdded = $query->map(function ($data) {
// try this if error $data['merchant_id']
return array(
'merchant_id' => $data->merchant_id,
'added_at' => $this->userTime($data->added_at)
);
})
dd($dateAdded);
Read Collection documentation here: https://laravel.com/docs/5.8/collections
You should use the selectRaw statement and let your DB do this logic for you if you don't want to loop over the result set.
For example if your underlying database is MySQL you can use the CONVERT_TIMEZONE function and do something like this.
BlogCategory::selectRaw('merchant_id, CONVERT_TZ(added_at, "GMT", "MET") as added_at')
->where('site_id', $site_id)
->get();

Query using eloquent whereMonth where date is string

In one of the tables a column with type of varchar contains a date with the following format day-month-year. I would like to run a query using eloquent on that table with whereYear and whereMonth, but I get an error since the column booking_date is not of type Date.
The query I am trying to run is
MyTable::whereYear('booking_date', '=', $year)
->whereMonth('booking_date', '=', $month)
->get();
And getting the following error
"SQLSTATE[42883]: Undefined function: 7 ERROR: function pg_catalog.date_part(unknown, character varying) does not exist\nLINE 1: ...\" = $1 and \"said_table\".\"deleted_at\" is null) and extract(ye...\n ^\nHINT: No function matches the given name and argument types. You might need to add explicit type casts.
Is there a way to cast the string value to a date before querying it, maybe with using raw expressions? If yes, any hints would be great.
If this field is going to be a date on the particular model all the time (and with a name like 'booking_date', it might well be), it is even easier than having to deal with it on every query. You can cast it within the dates field on the model itself:
protected $dates = [
'booking_date',
];
By default, Eloquent will convert the created_at and updated_at columns to instances of Carbon, and the above will do the same for booking_date. No further casting required. From Laravel docs on date mutators
You may easily achieve that thanks to Carbon library which is included within Laravel:
use Carbon\Carbon;
$targetDate = Carbon::now()->year($year)->month($month);
MyTable::whereYear('booking_date', '=', $targetDate)
->whereMonth('booking_date', '=', $targetDate)
->get();

Laravel Eloquent: count($result) vs $result->count()

I'm a bit new to this, and was originally trying to check if my model was returning results with isEmpty(), but thought I'd try count() instead, then I came across the following:
I've got the following code, which returns data from my model:
$results = Game::where('code', '=', $code)->with('genre', 'creator')
And whether I use first() or get() combined with count(result) or $results->count() I get different values, and I'm not sure why.
when using ->first()
dd($results->count()) = 11930 // Number of rows in the db
when using ->get()
dd($results->count()) = 1 // What I'd expect the query to return
when using ->first()
dd(count($results)) = "count(): Parameter must be an array or an object that implements Countable"
when using ->get()
dd(count($results)) = 1
I don't understand 1) why when using first, the count is the same as every row in the db. 2) Why count() can't be used with first().
Is anyone able to shed some light as to why I can't use count on first as I'd like to?
Update:
I'm also not able to use ->isEmpty() with ->first() but can with ->get()...?
When I try using it with first, I get Illuminate\Database\Query\Builder::isEmpty does not exist.
Disclaimer: I'm not sure why your database count and your results count aren't the same, however I can shed some light on the different types of count.
Game::where('code', '=', $code)->count();
This is being called on a query builder instance. It is run on the database query, without selecting all the rows. Check out the title Aggregates here: https://laravel.com/docs/5.7/queries
Game::where('code', '=', $code)->get()->count();
As soon as your use get() laravel selects the rows, boots them all as models, and creates a collection. This count is on the collection (a bit like an array) so just gets the number that are returned (i.e. if they are paginated or anything like that it will just get that amount). Check out Count here.
Game::where('code', '=', $code)->first()->count();
This is being run on the first returned model... unless you've written it, a default laravel model won't have a count() method.
count($results)
Finally, count() when not a class method is just the default php function that returns the length of an array or other object (documentation).
First of all,
get() returns collection of objects while first() returns modal object of query.
$results = Game::where('code', '=', $code)->with('genre', 'creator')
dd($results->count()) = 11930 // Number of rows in the db
when using ->get()
$results = Game::where('code', '=', $code)->with('genre', 'creator')->get()
dd($results->count()) = 1
because it has collection, which contains numbers of objects of database data. As ->count getting only one collection so it returns 1.

Laravel i will get integer in DB query

after returning $query from this:
$query = DB::table('pets')->select('id')->where('id', '=', $pet->id)->where('user_id', '=', Auth::id())->get();
for example i get this result : [{"id":"66"}]
how can i get only 66 as integer?
Thanks!
Instead of get() which returns the entire collection of selected data, use value('id') to get the first value of the id field. You also wouldn't need select('id') if you use this method.

Laravel Eloquent using paginate with whereIn

Hi I have a query that looks roughly like this
Comment::join('users', 'users.id', '=', 'comments.user_id')
->whereIn('comments.id', $ids)
->paginate(5);
where $ids is an array of comment ids. Changing the paginate to get() works but I want to use paginate as it returns many built-in useful results such as next_page_url etc. So how do I modify the query to utilize both whereIn and paginate together?
I found out the issue later on, I forgot to serialize the object before I return the result. A simple toArray() has done the trick.

Resources