Laravel not returning join query to blade - laravel

I have two queries, one is lighter on data by using the pivot table as a filter to get data from the main table (student in this case).
$students=\DB::table('student')->join('school_student', 'student.id', '=','school_student.student_id')->get();
This returns a query result from the controller. But will not load into the blade:
$this->layout->content=\View::make('admin.students.index')->with('student', $students);
Whereas this versions returns a similar more data heavy (i.e. outputs all school data each time)
but works in blade.
$students = \Student::with(array('schools' => function($query){$query->where('school_id', '=', 1);}))->get();
Is it simply that DB and view are incompatible?
If so what is the Laravel 4 method to query one table and it's pivot only.
Any help appreciated.
In the blade
#if($student->count())
The first example produces this error:
Call to a member function count() on a non-object

DB::...->get() returns an array, so you can't call ->count() on it (hence "non-object"), but instead you need count($students).
The reason ->count() works when you do the 'more data heavy' method is that you're using Eloquent and it returns Eloquent Collections.
So, basically, you're doing two different things and expecting to treat them the same.
Also, while I'm here I should point out that I think your Eloquent query isn't quite right. First off you're hardcoding the id as 1 (whereas in the DB-style query you don't care about the school ID, and you just use it to join to the pivot table - maybe you used an incomplete query), but also you're using with but you should probably look at has. with eager-loads models, but has is what you want if you just want to check for a condition on a join table.

Related

What is the different between laravel PLUCK and SELECT

I found that laravel 'pluck' return an plain array and 'select' return an object. Can anyone explain it to me have any other different between two this?
thank you.
Pluck is a Laravel Collections method used to extract certain values from the collection. You might often want to extract certain data from the collection i.e Eloquent collection.
While Select is a normal selection of either multi or specific columns. They are
By using Pluck you only ask to return necessary fields, but with get you will pull all columns. Also select does the same & the difference here is between the returning result. Using pluck cause returning the final result as an array with pair of given arguments, but select return an array (or object) which every single child contain one row.
$name = DB::table('users')->where('name', 'John')->pluck('name');
Select
EX : DB::table('users')->select('id', 'name', 'email)
Select is a method sent to the database that Laravel will translate as
SELECT id, name, email FROM users
This will select the data of the columns you asked and nothing else. It allows you to be more efficient with your request by only asking the required data. Take the example above and image that the user is a Facebook user. It has a ton of data on it, plus relations to other tables. If you just want to display the name, email and a link to the user profile, doing this request!
For more info and knowing more about the expected response visit : https://laravel.com/docs/9.x/queries#select-statements
Pluck
EX:
$users = DB::table('users')->where('roles', '=', 'admin')
$emails = $users->pluck('email')
The Pluck method retrieves the values in a collection that you already got from the Database and that is now a Laravel Collection. This allows you to create an array of the plucked data, but will not improve the performance of your request, as in the Example above, the $users would hold all data of all the admin users.
Since it does not improve performance, what good is it then ?
The pluck would be useful for example to separate some datas in different variables depending on where. You might need the users data for some stuffs, but also want to display a quick list of all emails together.
For more info about the pluck method and understand how to create a keyed array from a second column, visit the docs here: https://laravel.com/docs/9.x/collections#method-pluck
Pluck function normally used to pull a single column from the collection or with 2 columns as key, value pairs, which is always be a single dimension array.
Select will return all of the columns you specified for an entity in a 2 dimensional array, like array of selected values in an array.
Note: Pluck function is a collection function which happens after the data is fetched. Select is a query builder function that builds query to perform in the database server.
Actually select is used inside DB queries, which can affect the performance by limiting the pulled columns. However, Pluck is Laravel Collection's method, so you can use pluck after you pull the data from DB.

How to use Query Builder to make a relation in an array? Laravel

I would like to make a relation with query builder... I have three tables, and I would like to join the tables for work with the function.. I'm working in a model.. not in a controller
This is my function
public function map($contactabilidad): array
{
$relation = DB::table('tbl_lista_contactabilidad')
->join('tbl_equipo_postventaatcs', 'tbl_equipo_postventaatcs.id', '=', 'tbl_lista_contactabilidad.postventaatc_id')
->join('users', 'users.id', '=', 'tbl_equipo_postventaatcs.asesor_id')
->get();
return [
$contactabilidad->$relation->name,
$contactabilidad->postventaatc_id,
$contactabilidad->rif,
$contactabilidad->razon_social,
$contactabilidad->fecha_contacto,
$contactabilidad->persona_contacto,
$contactabilidad->correo_contacto,
$contactabilidad->numero_contacto,
$contactabilidad->celular_contacto,
$contactabilidad->comentarios,
$contactabilidad->contactado,
$contactabilidad->respuesta->respuesta
];
}
Query\Builder is best thought of as the primary tool used by Eloquent, but is, nontheless, a completely different package. Query\Builder's purpose is to decouple SQL syntax from the logic that feeds into it, whereas Eloquent's purpose is to decouple that logic from table structures and relationships. So only Eloquent supports Model and Relation classes, Query\Builder does not. And what you're asking for has to do with Relations, so in short, you're kind of barking up the wrong tree.
By the way, I'm differentiating 'Query\Builder' here because Eloquent also has its own wrapper for that class called Eloquent\Builder that shares most of the same syntax. For better or for worse, Eloquent attempts to allow the developer to interact with it in a way that's familiar; not having to track a new set of method names even if you've been seamlessly dropped out of Eloquent and into a Query\Builder object via a magic __call method. It also does something similar regarding Eloquent\Collections vs. Support\Collections. But that can make things very confusing at first, because you have to just kind of know what package you're talking to.
So, to answer your question...
Build a Model class for each of your three tables
Apply relationship methods to each one to pre-configure the model with an awareness of your foreign keys
Call on them using lazy or eager-loading
Something else to note is that with() does not ask Eloquent to perform a JOIN. All it does is run the parent query, extract the key values from the result, run the child query using them in an IN() statement, and marrying the results together afterwards. That's what results in nested results. Speaking from experience, it's kind of a mess generating true JOIN statements off Model Relations and keeping the table aliases unique, so it makes sense this package just skips trying to do that (except with pivot tables on many-to-many relations). This also has the added benefit though, that your related tables don't need to live in the same database. A Query\Builder join() on the other hand, as you have there, would present all fields for all tables at the top-level.

How to Paginate Multiple Models in Laravel without overworking the memory

Im trying to figure out the best way to paginate in laravel when i am working with big datasets, the method i am using now is overworking the memory. this is what i am doing: i query from multiple tables, map the results etc, then merge multiple collections, and only after that do i paginate it, i realized though that this is a really bad way of going about this, because i am querying way to much data for no reason, and as the data grows the slower it will become.
the question is what would be the correct way?
i thought maybe i would paginate and then work with the data, the issue is that for instance if i was trying to sort all the merged data by date i wouldn't be getting the proper results because one table may have less data then the other...
here is some of the code to help with clarifying the question
first i will query two tables orders table and transactions table
$transactions = Transaction::all();
$orders = Order::all();
then i will send this all to a action to map it all and format it the way i need to with laravel resources
return $history->execute(['transactions' => $transactions, 'orders' => $orders]);
what this action does is simply map all the transactions and return a resource, then it will map all the orders and return resources for them as well, after which it will merge it all and return the result.
then i take all of this and run it through a pagination action which uses the Illuminate\Pagination\LengthAwarePaginator class.
the results are exactly the way i want them its simply a memory overload.
i tried paginating first instead of doing
$transactions = Transaction::all();
$orders = Order::all();
i did
$transactions = Transaction::orderBy('created_at' 'desc' )->paginate($request->PerPage);
$orders = Order::orderBy('created_at' 'desc' )->paginate($request->PerPage);
and then run it through the action that returns resources.
there are a few issues doing this, firstly, i will no longer get back the pagination data so the app won't know the current page or how many records there are, secondly, if for example the orders table has 2 records, and the transactions table has 10 records, event though the dates of the orders table is after those of the transactions table they will still get queried first.
Use chunk method or paginate
Read documentation.

Laravel/Eloquent pagination and groupBy for a postgres materialized view model

I've created a materialized view: accounts_index that has a couple left joins, so I need to do a group by with the eloquent model. I also need to paginate the collection and am having trouble nailing the order of things. The materialized view:
CREATE materialized VIEW accounts_index
AS SELECT a.account_uuid,
a.account_no,
a.person_owner_uuid,
a.company_owner_uuid,
a.account_group_uuid,
a.account_scope_uuid,
a.created_at,
a.deleted_at,
s.service_uuid,
s.status,
st.service_type
FROM accounts a
LEFT JOIN services s
ON a.account_uuid = s.account_uuid
LEFT JOIN service_types st
ON s.service_type_uuid = st.service_type_uuid
The eloquent model can grab that table like so: AccountIndex::all();.
I could paginate that: AccountIndex::paginate(); or do a groupBy: AccountIndex::all()->groupBy('account_uuid');, but lost on how to combine the two. Some attempts:
AccountIndex::all()->groupBy('account_uuid')->paginate(): Method Illuminate\Database\Eloquent\Collection::paginate does not exist.
AccountIndex::paginate()->groupBy('account_uuid');: returns the collection without paginating.
$accountsIndex = collect(\DB::table('accounts_index')->get());
$accountsIndex->groupBy('account_uuid')->paginate();: Same Method Illuminate\Support\Collection::paginate does not exist. exception.
The main problem I'm trying to solve is that these joins will be returning accounts that have multiple services (so multiple rows) and I need to then group by the account_uuid. Thanks in advance for any insights!
paginate method is related to Illuminate\Database\Query\Builder or Illuminate\Database\Eloquent\Builder classes, it is not exists in Collection class,
the corresponding method for it in Collection class is forPage method, you can get more information from the documentation
almost
AccountIndex::groupBy('account_uuid')->paginate()
paginate actually DOES something
groupBy() is just writing SQL just like ->where() ->join() etc that all prepares an SQL statement you can try by running ->toSql() returns an sql string.
get() all() paginate() all actually do something e.g. execute the SQL.

Laravel - How to relate two collections like Eloquent method "belongsToMany" and "with"

How can you combine two collections, one being the collection of parent items together combined with your collection of child items?
I would like something like using the method with and belongsToMany,but in this scenario I cannot use both methods correctly because one table is in another schema and the pivot table is in another schema.
Area::with('permissoes')
->where('sistema', '<>', 'S')
->get()
Most Eloquent eagerloads are done with separate queries that just use an IN statement on keys from the previous one. Pivot tables are the exception. It sounds like you need to explicitly tell the Model relation what database your pivot table is in. See my answer here: belongsToMany relationship in Laravel across multiple databases

Resources