leftJoin method in Eloquent ORM? - php

I'm beginner in Laravel and I'm using 5.5 version.
Is there a method leftJoin in Eloquent ORM?
I know there is one on DB facade (query builder), but if I want to use Eloquent only is there a leftJoin method?
Let's suppose, as an example, I have a model CarBrand and another one CarModel.
CarBrand have a relationship type hasMany with CarModel, and CarModel belongsTo CarBrand.
Suppose I want to find CarBrand's id's without CarModel correspondence.
I found on this site, several responses like this:
CarBrand::leftJoin('CarModelTableName',
'CarBrandTableName.id','=','CarModelTableName.carBrandId')->
whereNull('CarModelTableName.carBrandId')->first();
I have checked and it does function as a left join :)
But in this case is ::leftJoin an Eloquent method or silently it goes to DB facade?
I can't find any for leftJoin in Laravel 5 official docs other than DB facade.
Any links would be appreciated.
Hope I was clear,
Thank you for your attention.

I think I found the answer....
I find out that I can use something like:
LaravelModellName::AnyQueryBuilderMethod
so that's why is using DB facade methods
The problem in my primary question could be solved 100% in eloquent way using doesntHave model method:
$result = CarBrand::doesntHave('RelationshipNameWithCarModel')->get();

Related

How do I create a custom relationship in laravel?

Is it possible to create custom relationships in Laravel like this,
SELECT tasks.*
FROM tasks
LEFT JOIN priorities ON tasks.priority_identifier LIKE CONCAT('%', priorities.identifier)
WHERE priority.id = 10
I could use query builder to create this join but how can i return this as a laravel relationship ?
Edit
I'm trying to do this without using existing relationship methods(hasMany, hasOne etc)
Yes, you can add conditions to Laravel relations just like any other query builder. I don't know what your relation will look like, but you could do this for example:
public function tasks()
{
return $this->hasMany(Task::class)
->where('priority', 10);
}
I don't think you can create a custom relationship, unless overriding Eloquent base class.
And add your own.
But you can use Eloquent scopes alternative to custom relationships.
Also take a look here and here

How to join three tables with eloquent using a model

I've never studied Eloquent. I am studying APIs and I want to get some data as kickly as possible, without writing sql, what is I usually do.
I have the tables: "house" related to "announcement" (one to one) and the "announcement" table is related to "advertiser" (one to many).
When I tried
$house = \App\House::where('house_id', $id)->with('announcement', 'advertiser')->first();
I get the error: announcement undefined method.
I think I set up the relationship on the models correctly so I didn't include them here. I want to join using the model House because I am not using the default connection when using Eloquent.
with() must be placed at first, and specify your relationships in an array (if you load more than one)
$house = \App\House::with(['announcement', 'advertiser'])->where('house_id', $id)->first();
Edit :
Sorry, i haven't seen that it's a nested relationship
You can use this code instead of the above one :
$house = \App\House::with(['announcement', 'announcement.advertiser'])->where('house_id', $id)->first();
for a nested relationship use dot like announcement.advertiser
$house = App\House::with(['announcement', 'announcement.advertiser'])->where('house_id', $id)->first();

laravel Eloquent join and Object-relationship mapping

Ok so i'm kind of newish to eloquent and laravel (not frameworks tho) but i hit a wall here.
I need to perform some queries with conditions on different tables, so the eager load (::with()) is useless as it creates multiples queries.
Fine, let use the join. But in that case, it seems that Laravel/Eloquent just drops the concept of Object-relationship and just return a flat row.
By exemple:
if i set something like
$allInvoicesQuery = Invoice::join('contacts', 'contacts.id', '=', 'invoices.contact_id')->get();
and then looping such as
foreach ($allInvoicesQuery as $oneInvoice) {
... working with fields
}
There is no more concept of $oneInvoice->invoiceFieldName and $oneInvoice->contact->contactFieldName
I have to get the contacts fields directly by $oneInvoice->contactFieldName
On top of that the same named columns will be overwrited (such as id or created_at).
So my questions are:
Am i right assuming there is no solution to this and i must define manually the field in a select to avoid the same name overwritting like
Invoice::select('invoices.created_at as invoice.create, contacts.created_at as contact_create)
In case of multiple joins, it makes the all query building process long and complex. But mainly, it just ruins all the Model relationship work that a framework should brings no?
Is there any more Model relationship oriented solution to work with laravel or within the Eloquent ORM?
Instead of performing this join, you can use Eloquent's relationships in order to achieve this.
In your Invoice model it would be:
public function contact(){
return $this->belongsTo('\App\Contact');
}
And then of course inside of your Contact model:
public function invoices(){
return $this->hasMany('\App\Invoice');
}
If you want to make sure all queries always have these active, then you'd want the following in your models:
protected $with = ['Invoice']
protected $with = ['Contact'];
Finally, with our relationships well defined, we can do the following:
$invoices = Invoice::all();
And then you can do:
foreach($invoices as $invoice)[
$invoice->contact->name;
$invoice->contact->phone;
//etc
}
Which is what I believe you are looking for.
Furthermore, you can find all this and much more in The Eloquent ORM Guide on Laravel's site.
Maybe a bit old, but I've been in the same situation before.
At least in Laravel 5.2 (and up, presumably), the Eloquent relationships that you have defined should still exist. The objects that are returned should be Invoice objects in your case, you could check by dd($allInvoiceQuery); and see what the objects are in the collection. If they are Invoice objects (and you haven't done ->toArray() or something), you can treat them as such.
To force only having the properties in those objects that are related to the Invoice object you can select them with a wildcard: $allInvoicesQuery = Invoice::select('invoices.*')->join('contacts', 'contacts.id', '=', 'invoices.contact_id')->get();, assuming your corresponding table is called invoices.
Hope this helps.

The difference between an Eloquent Model and a Model?

So, i'm confused with this :
In Laravel's official documentation, they say :
The Eloquent ORM included with Laravel provides a beautiful, simple
ActiveRecord implementation for working with your database. Each
database table has a corresponding "Model" which is used to interact
with that table.
Ok util here all is Great, i get it !
So I make a migration to create a database : php artisan make:migration create_items_table --create="items"
Great until here too :)
So theoretically speaking, when i will make : php artisan make:model Item , Laravel will create a php class ( which is used to interact with items table) :
class Item extends Eloquent {
...
}
But,in real world, when i make : php artisan make:model Item , Laravel creates php class ( which is used to interact with items table) ::
class Item extends Model {
...
}
So Why Model and not Eloquent ?? Am i missing sth ?
And What's the difference between Eloquent Model and Model.
And if there's a difference, when should i use Eloquent and when Model ... ?
Thank you ^^
I found the solution for my question ...
So Normally you must add an alias to your config/app.php
'aliases' => [
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
And when you create a model, Laravel will use Eloquent; instead of use Illuminate\Database\Eloquent\Model; this why i think, some person may use Model, when other may use Eloquent , it's just a matter of give a meaning sense to the namespace :3
Eloquent is the name given to the ORM (Object-relational mapping) that ships with Laravel. Eloquent allows you to interact with your tables as though they were objects, however Eloquent is unaware of the actual columns you have on your table.
Let's consider the simple User model. We want this model to query records on our users table.
class User extends Eloquent {
protected $table = 'users';
}
That there is a very simple model. Now, instead of querying like this.
$user = DB::table('user')->find(1);
You can query like this.
$user = User::find(1);
Eloquent itself uses its own query builder but does fall back to the standard query builder. This means it has all the methods on the query builder available to it, and more.
The benefits here are:
You don't have to specify your table name on every call.
The code reads a whole lot better, it's syntactical sugar.
You can create complex relationships between tables and use eager loading.
You can make use of functionality such as mass assignment protection and setters/getter.
I've only touched on Eloquent. There is so much more to it. I suggest you take a look at the following resources.
Eloquent Documentation
Dayle Rees' Code Happy
For more exact simple example click here

Laravel and Eloquent : Update multiple Model & Relationships

How can you update multiple models and their relations at the same time?
For example:
EditPost is a model with a editor() relation belongsTo User model.
Now lets say I have to update the editor in all the EditPost objects with original_post_id
EditPost::where('original_post_id',4)->get()
Possible Solutions
a. To do it by referring the user by ID instead of by the Model User
EditPost::where('original_post_id',4)->update(array('editor_id',3));
b. To do it by a foreach and saving each model
However
Neither of these appeals to me as they don't gel in general with the object concept of Eloquent or they would mean doing multiple updates instead of one.
I was wondering if Eloquent itself had a more elegant solution
You don't specify the other end of the association, but I assume you are looking for something like this?:
$user = User::find(3)
EditPost::where('original_post_id', 4)->editor()->associate($user)->save();

Categories