Eloquent One To Many issue - laravel

i have a question related to the title.
so i have this models (i have more code and models behind if u need tell me)
Cliente Model
protected $table = 'cliente';
protected $primaryKey = 'id_cliente';
public $timestamps = false;
public function seguroCarro()
{
return $this->hasMany('App\SeguroCarro', 'id_seguro_carro');
}
SeguroCarro Model
protected $table = 'seguro_carro';
protected $primaryKey = 'id_seguro_carro';
public $timestamps = false;
public function cliente()
{
return $this->belongsTo('App\Cliente', 'id_cliente');
}
Question:
This Cliente::find(1)->seguroCarro get the seguro_carro with id 1 and not with id_cliente 1 but this SeguroCarro::all()->where('id_cliente',Auth::user()->cliente->id_cliente) get the 3 rows seguro_carro i need
i dont get why this happen but i want understand why
Atencion:
this Cliente::find(1)->seguroCarro is a abreviation for you guys for my code Auth::user()->cliente->seguroCarro [my Auth::user()->cliente have the id 1]
img of rows on seguro_carro table
Thank you for the time guys

The relationship on your App\Cliente model is specifying the wrong key. The second parameter to the hasOne/hasMany relationship is the name of the foreign key field on the related object. In this case, the foreign key on the related object (App\SeguroCarro) is id_cliente, not id_seguro_carro.
Your current relationship will get the seguro_carro records where seguro_carro.id_seguro_carro = cliente.id_cliente, which is not what you want.
The relationship should be changed to:
public function seguroCarro()
{
return $this->hasMany('App\SeguroCarro', 'id_cliente');
}
This will get the seguro_carro records where seguro_carro.id_cliente = cliente.id_cliente, which is what you want.
The belongsTo relationship on your App\SeguroCarro is correct.

Related

Laravel Eloquent relationship data retrieve

I have below code to get data from database,
$profile = Profiles::find(1);
$currency = Profiles::find($profile->currency_id)->currency;
Then created a relationship in the model as below,
class Profiles extends Model
{
use HasFactory;
protected $table = 'Profiles';
protected $primaryKey = 'profile_id';
public function Currency()
{
return $this->belongsTo(Currencies::class, 'currency_id');
}
}
class Currencies extends Model
{
use HasFactory;
protected $table = 'Currencies';
protected $primaryKey = 'currency_id';
public function profile()
{
return $this->hasOne(Profiles::class, 'currency_id');
}
}
Problem is that there is only 1 profile and 100 currency, currency_id is a foreign key in Profiles table,
I could not get data and get this error, Trying to get property 'currency' of non-object"
If i use $currency = Profiles::find(1)->currency; then it retrieve first row of Curriencies table which is not required data.
How can I get currency row for that specific profile?
The problem is that the find() method will look for the primaryKey and in your second call the currency_id is not the pk.
Two solution for you:
replace the find by a where clause like so: $currency = Profiles::where('currency_id',$profile->currency_id)->value('currency')
Or a more Laravel way to do it, through the relationship $currency = $profile->currency;

Getting all values from laravel relationship table

I have below relationship in laravel model for Bills,
protected $table = 'purchase_bills';
protected $primaryKey = 'bill_id';
public function vendors()
{
return $this->belongsTo(Vendors::class);
}
Below relationship for Vendor,
protected $table = 'vendors';
protected $primaryKey = 'vendor_id';
public function bills()
{
return $this->hasMany(Purchasebills::class, 'bill_id');
}
Now i am trying to get all bills of specific vendor with below code,
$bills = Vendors::find(1)->bills()->where('vendor_id', $vendor_id);
return Datatables::of($bills)->make();
But it always returns only 1 row from a table if it is first, even though there are many bills.
How can i get all bills from that vendor_id?
I could resolve the issue, actually, it was a wrong foreign key assignment in the model,
Below is correct one.
return $this->hasMany(Purchasebills::class, 'vendor_id');

How to join two or more table using laravel eloquent method?

Little confused about eloquent-relationship joins, since I used to get the result by query builder so far. Referred with other related questions still, I am not clear. Please explain me with a better example.
Model 1 - customer
Model 2 - customer_items (relating customer_id and item_id)
Model 3 - items (details about items)
Now I want to list the item details that customer related to.
join customer_items with items where customer.id = customer_items.user_id and items.id = customer_items.item_id.
First define methods in models.
Customer.php // Customer model
class Customer extends Model
{
protected $table = 'customers';
protected $primaryKey = 'customer_id';
public function customerItems(){
//customer_id is a foreign key in customer_items table
return $this->hasMany(Item::class, 'customer_id');
// A customer will has many items thats why hasMany relation is used here
}
}
CustomerItem.php // CustomerItem
class CustomerItem extends Model
{
protected $table = 'customer_items';
protected $primaryKey = 'customer_item_id';
public function itemDetail(){
//customer_id is a foreign key in customer_items table
return $this->hasOne(Customer::class, 'customer_item_id');
//A Item will has single detail thats why hasOne relation used here
}
}
In CustomerController.php
use \Customer // define customer model path
public function getCustomerItem(Request $request)
{
// Eloquent query to get data
$customer_item_detail_data = Customer::with('customerItems.itemDetail')->get();
//it return all items of customers with item details
//$customer_item_detail_data = Customer::with('customerItems')->with('customerItems.itemDetail')->get(); you can also use in this way
}
Hope it helps. Thank you.
First, you would need to define your models as such:
class Customer extends Model
{
protected $table = 'customers';
public function items(){
return $this->hasMany(Item::class, 'customer_id');
}
}
class CustomerItem extends Model
{
protected $table = 'customer_items';
public function customer(){
return $this->belongsTo(Customer::class, 'customer_id');
}
}
Then you would call the the relationship as such:
$customer = Customer::find(1); // This will get the first customer in the DB
$itemsOfCostumer = $customer->items // This will return all the items of the customer
// Now let suppose we have an ItemCustomer and we would like to know the owner
$customerItem = CustomerItem::find(1); // Get the first item of a customer in DB
$customer = $customerItem->customer; // Ther you have the customer
This is just a small example. Stackoverflow is not an educational website which I would highly advise you to visit Laravel Relationship Docs. Over there you can learn much more and they have a really good series at Laracast about relationships (if you are visual learner) https://laracasts.com/series/eloquent-relationships
If I got well your question, you are looking for a query to get the item details.
$item_details = Items::
join('customer_items', 'customer_items.item_id', '=', 'items.id')
->join('customer', 'customer.id' '=', 'customer_items.customer_id');
Or you can get the same result doing:
$item_details = DB::table('items')
->join('customer_items', 'customer_items.item_id', '=', 'items.id')
->join('customer', 'customer.id' '=', 'customer_items.customer_id');

Laravel Eloquent, filtering from pivot table column

I need to filter the active clients from a route using Eloquent.
I'm working with a third party database that I can't modify. In my project I have two models: Cliente(client) and Ruta(route), which have a many to many relationship, so I added the belongsToMany relationship in my models.
The only column I'm interested from the pivot table is called DESACTIV, which tells me if a Client is deactivated for a Route.
Ruta model:
class Ruta extends Model
{
protected $connection = 'mysql2';
protected $table = 'truta';
protected $primaryKey = 'CODIRUTA';
public function clientes(){
return $this->belongsToMany(Cliente::class, 'tcpcarut', 'CODIRUTA', 'CODICLIE')->withPivot('DESACTIV');
}
}
Cliente model:
class Cliente extends Model
{
protected $connection = 'mysql2';
protected $table = 'tcpca';
protected $primaryKey = 'CODICLIE';
public function rutas(){
return $this->belongsToMany(Ruta::class, 'tcpcarut', 'CODICLIE', 'CODIRUTA')->withPivot('DESACTIV');
}
}
What I need is to get the active (or non deactivated) Clients given a specific Route.
I have done it on my controller like this:
$miRuta = Ruta::where('CODIRUTA','=',$ruta)->first();
$clientes = array();
foreach ($miRuta->clientes as $cliente){
if ($cliente->DESACTIV == 0){
array_push($clientes, $cliente->NOMBCLIE);
echo end($clientes)."<br/>";
}
}
And it works fine, but I don't think it's elegant. I know this can be archieved through Eloquent, I'm just to noob at it and don't know how to do it.
Maybe I could add the filter on the clientes method on my Ruta model, so it would return only the active Clients.
Or maybe It could be best to add a method on the Cliente model, like isDeactivated
I know it sounds like I know what I'm talking about but I need someone to hold my hand on this, I'm just too noob with Eloquent :/. Examples would be much appreciated.
You can use the wherePivot method to constrain a relationship based on values in the pivot table. You just need to add the following to your Ruta model
public function desactivClientes() {
return $this->clientes()->wherePivot('DESACTIV', 0);
}
And then you just have to modify the rest of your code a bit to use the constrained relationship. I'm also adding a null check because if this function does return null, which can happen if your table doesn't have a record where CODIRUTA matches whatever is in $ruta, then it will likely throw a fatal error trying to call a method on a non-object.
$miRuta = Ruta::where('CODIRUTA','=',$ruta)->first();
$clientes = array();
if ($miRuta !== null) {
$clientes = $miRuta->desactivClientes()->pluck('NOMBCLIE');
}

working with m:m relationships in eloquent outside laravel

I have been able to set up a m:m relationship in eloquent outside laravel and retrieve records but I have no idea how to add a new record as you dont create the pivot table in the code.
If these are my classes, how would i add a new instance to the M:M relationship between author and publisher?
<?php
include 'eloquent_database.php';
class Publisher extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'publisher';
protected $primaryKey = 'publisher_id';
public function authors (){
return $this->belongsToMany('Author', 'author_publisher', 'publisher_id', 'author_id');
}
}
class Book extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'book';
protected $primaryKey = 'book_id';
public function author() {
//related table name, pk in current table,
return $this->belongsTo('Author', 'author_id');
}
}
// Create the company model
class Author extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'author';
protected $primaryKey = 'author_id';
public function books()
{
//related table, fk IN related table,
return $this->hasMany('Book', 'author_id');
}
public function publishers (){
return $this->belongsToMany('Publisher', 'author_publisher', 'author_id', 'publisher_id');
}
}
I would also need to know how to delete one too. I have seen this documentation http://laravel.com/docs/4.2/eloquent#working-with-pivot-tables but i dont really follow it
Id really appreicate an exxample of how to add and delete a new instance. Also onine there seeems to be so many different versions its hard to find which docs to follow as the code i have works but i didnt get it from the docs - just trial and error
Thanks a lot in advance
edit:
in repsonse to Rays comment i do have a pivot table in the database called author_publisher with author id and publisher id but i have no idea how to work with this pivot table. Do i have to create a class for it? I dont really understand
Here is a reference to said table in the code above
return $this->belongsToMany('Author', 'author_publisher', 'publisher_id', 'author_id');
When having a M:M relationship, make sure you have a table that translates the relationship between author and publisher. An example table could be composed of entries including both author_id and publisher_id. From what you have provided, you lack such a table.
There's another case if you do not have such a table. In order for such a M:M relationship to work, the author table must contain a column called "publisher_id" for simplicity. Likewise the publisher table must contain a column called "author_id". Then in the author model, return $this->hasMany('Publisher', 'author_id') and in the publisher model, return $this->hasMany('Author', 'publisher_id'). You should get the correct answer.

Resources