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

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

Related

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 do I make relationships for 4 tables including pivot table

I have many to many relationships. Imagine I have 3 tables. Something like this :
users.
roles.
role_user.
(This example is also provided in laravel's docs).
Now I'm doing this : $user->roles() which returns roles with Pivot attributes . but what I actually want to do is move forward and also get the appropriate data from the 4th table. something like this $user->roles()->types(); and the difficult thing is that this types() belongs to pivot table.
Do you know how to do this kind of thing ? where Do I write types() function?
Assuming your "Roles" model has the relationship set you may try
$user->roles()->with("types")
Source docs: https://laravel.com/docs/5.7/eloquent-relationships#eager-loading

How to create models for dynamically generated tables (on the fly)?

I stumbled upon this problem today. My project has a few tables, for which I have created their dedicated Models. However, my project allows user to create dynamic tables.
How do I create relationships or models for/between these dynamically generated tables?
I would not recommend to create Eloquent Models on dynamically generated tables, because Eloquent Models are here to help developers with already created database tables (features like relationships, scopes, attributes casting are usually defined for existing database tables).
What would be my recommendation? Use the Query Builder instead. You will have almost the same functionalities of Eloquent Models, except without model.
Instead of having something like:
DynTable::where('foo', 123)
->where('bar', 456)
->first();
You will have the following:
DB::table('dyn_table')
->where('foo', 123)
->where('bar', 456)
->first();
Basically, the same. But, with the benefit that you can specify any table name to the Query Builder, but you can't change the table name to an Eloquent Model (in a running script).

Laravel Eloquent model data from 2 tables

I've just started using Laravel and I'm coming from a different system using an existing database. In this system there are 2 users table, one stock with the CMS and one custom one.
I want to create an Eloquent model which retrieves data from both tables into one model. I know I can use the following to create a relationship.
$this->hasOne('App\SecondUser', 'id', 'id);
But this results in 2 sql queries, and I want to join results from 2 tables before returning the model, in one join statement. How do I do this?
That might be a bit more complicated that you would expect.
First of all you have to use \DB facade to join the two collections(arrays) and then recreate the Eloquent collection from these arrays using Collection's make method.
More info about the Collection class here
An easier way might be to join them using standard laravel relationships and user something like Model::user->with('relation')->get.
But this will still create 2 queries (still relatively fast).

Dynamically set the table name in a "has many" relation model

In my database schema, I have multiple tables that hold generic data for objects, for instance I have a user table and a user_data, post table and post_data, and so. these *_data tables all hold a foreign key to the object and a pair of key-value. now in my laravel models I would like to have a single data models for these tables (rather than a model for every single one) and represent the has_many relation in a dynamic way where somehow I can define the table name according to the parent model. I think the parent model would have something like:
return $this->hasMany('data');
but I don't know how to express the inverse relation nor how to tell laravel which *_data table to use. so my question is, is it possible? and if so, how?
You have two options.
Either create a model for each data_* table and use the relation as stated with $this->hasMany('data'); and $this->belongsTo('User'); in the data table and the user table.
Or you can use Polymorphic relations, I personally prefer the polymorphic relations solution, more neat.

Resources