How to define relationship in Laravel using composite keys?
I have 2 tables which have 2 primary keys, order [id_order, id_trip] and detail order [id_trip, id_seat].
I tried to get $order->detail_order->id_seat in index.blade.php, but the error is Array to string conversion (View: D:\xampp\htdocs\travel\resources\views\order\index.blade.php)
I think I have a mistake in defining relationship in model. Here's my code :
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Traits\CompositeKeyTrait;
class Order extends Model{
use CompositeKeyTrait;
protected $table = "order";
protected $fillable = [
'id_order',
'id_trip',
'id_users_customer',
'date_order',
'id_users_operator'
];
protected $primaryKey = ['id_order', 'id_trip'];
public function detail_order(){
return $this->hasMany(Detail_Order::class);
}
}
Detail_Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Traits\CompositeKeyTrait;
class Detail_Order extends Model{
use CompositeKeyTrait;
protected $table = "detail_order";
protected $fillable = [
'id_trip',
'id_seat',
'id_users_feeder',
'id_order',
etc
];
protected $primaryKey = ['id_trip', 'id_seat'];
public function order(){
return $this->belongsTo(Order::class, 'id_order', 'id_trip');
}
}
index.blade.php
#foreach($order as $o)
<tr>
<td>{{ $o->detail_order->id_seat }}</td>
</tr>
#endforeach
Does anyone have any idea? Thanks.
Laravel does not support Composite Primary Key. You hit "Array to string conversion" error becouse Laravel try to cast array to string.
protected $primaryKey = ['id_order', 'id_trip'];
You can't. Eloquent doesn't support composite primary keys.
But you can do using an open-source package called LaravelTreats.
Hope this helps you
Ref: https://stackoverflow.com/a/36995763/10765839
Related
Hello guys I am working on a laravel project for making api for passing the database value in json format but the problem is I have a users table in this table 2 ids 1 is primary key and second is business _id I want to get data according to business_id but it's getting data by id please help me how to solve this issue.
Here is my model code
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class user extends Model
{
protected $table = 'business';
}
Here is my Controller Code
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\user;
class GetController extends Controller
{
public function databybusinessid($business _id){
$users = new user();
$users = user::find($business _id);
return response()->json($users);
}
}
Thank you so much
You are using user::find($business _id)
find() method will automatically search by the primary key but none is defined in your model and Eloquent can't decide which one to pick from your table. Therefore, you should explicitly set your primary key in your model by adding the following line.
class user extends Model
{
protected $table = 'business';
protected $primaryKey = 'business_id';
}
If in doubt, you can also fetch database record by a specific column using where
$users = user::where('business_id', '=', $business _id)->get()
Laravel documentation about Eloquent ORM
https://laravel.com/docs/5.8/eloquent
find() Retrieve a model by its primary key..
So you have to use your code as:
$users = user::where('business_id',$business_id)->first();
// Notice first() Retrieve the first model matching the query constraints...
Or you can change your primary code in model
namespace App;
use Illuminate\Database\Eloquent\Model;
class user extends Model
{
protected $table = 'business';
protected $primaryKey = 'business_id';
}
find() works only on primary key. you need to use where instead.
or you can define business_id as primary key in your User model.
protected $primaryKey = 'business_id';
public function databybusinessid($business _id){
$users = new user();
$users = user::where('business_id',$business _id)->first();
return response()->json($users);
}
Project model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
protected $table = 'project';
protected $primaryKey = 'project_id';
}
Developer model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Developer extends Model
{
protected $table = 'developer';
protected $primaryKey = 'id';
}
I want to join this two model as the SQL below :
SELECT developer.developer_name, count(project.dev_id)
FROM project
JOIN developer ON developer.id = project.dev_id
GROUP BY developer.developer_name
Can someone help me? I am confused when looked through different documentation.
Please guide me the correct way.
Create a projects relation in Developer model.
public function projects()
{
return $this->hasMany(\App\Project::class, 'dev_id')
}
Then you can get all developers with number of projects they are handling using
Developer::withCount('projects')->get();
You can do this using below query and also you can do this by eloquent query for this you have to define relationship in model.
DB::table('project')
->join('developer', 'project.dev_id', '=', 'developer.id')
->select('developer.developer_name', DB::raw("count(project.dev_id) as count"))
->groupBy('developer.developer_name')
->get();
I want to join three tables. Here is the DB model in server:
lecturers
id - integer (PK)
......
examination
id - integer (PK)
.....
exam_supervision
lecturer_id - integer (FK)
exam_id- integer (FK)
Model relation as I implemented in laravel.
```
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Examsupervision extends Model {
public $timestamps = false;
protected $table = 'exam_supervision';
protected $fillable = ['lecturer_id', 'exam_id'];
}
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Examination extends Model {
public $timestamps = false;
protected $table = 'examination';
protected $fillable = ['name', 'module_id', 'startdate', 'enddate', 'duration', 'type', 'code', 'status'];
}
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Lecturers extends Model {
public $timestamps = false;
protected $table = 'lecturers';
protected $fillable = ['user_id', 'address', 'phone'];
}
```
lecturers, examinations and exam_supervision which is M:M. What I want is find all the examinations of a lecturer.
My code
public function lecturerViewExaminations($id)
{
what code to get all exam for a lecturer..say ID 129
}
Returning me empty set. WHat am I doing wrong? It is easy in SQL syntax but in laravel I am finding it very confusing
What i understand from your question is:
You have one model (Examsupervision) and want the relations examinations and lectures
You can use Eloquent: Relationships
First create a model. In this case your model name would be something like Examsupervision.
In your model(Examsupervision) you can define your relations. In this case examinations and lextures
Create for every relation a new model. So you will have 3 models (Examsupervision, Examinations, Lectures).
Now in your model Examsupervision create a new relation function.
public function lectures()
{
return $this->hasMany('App\Lectures');
}
public function examinations(){
return $this->hasMany('App\Examinations');
}
In your database table "lectures" and "examinations" create a new key with the name examsupervision_id. This key will be the id of the Examsupervision row.
Now in your code when you want the get all the lectures of a given Examsupervision you can do this.
$examsupervision = Examsupervision::find($id); //$id = the Examsupervision you want to retrieve
$lectures = $examsupervision->lectures; //This will return all the lectures connected to examsupervision
And for examinations you can do the same with:
$examsupervision = Examsupervision::find($id); //$id = the Examsupervision you want to retrieve
$examinations = $examsupervision->examinations;
Hope this helps
You are missing ->get() after the last where.
$examinations= Examsupervision::with('lecturers', 'examinations')->where('lecturer_id', 'id')->where('exam_id', 'id')->get();
Model::with() is for relation, Use just ->get()
$examinations=Examsupervision::with('lecturers', 'examinations')->get();
You already have relation for lecturers and examinations.
If not worked, share Model Examsupervision
When I select all records using eloquent Model::all() method it's give me soft delete record too.
Model class
protected $table = 'tr_fl_tax_charges';
protected $primaryKey = 'fl_tax_id';
use SoftDeletes;
protected $softDelete = true;
protected $dates = ['deleted_at'];
Controller class
Case 1
public function index()
{
$tax = Tax::all();
return $tax;
}
it's give me all record including soft deleted row.
Case 2
public function index()
{
$tax = Tax::all()->where('deleted_at' , '=', null);
return $tax;
}
this case give me correct output and not including soft deleted rows but it's give me all the columns and I don't need all columns.I need only 4 columns.
Case 3
If I add column name that need in all() method it's give me soft deleted row too.
public function index()
{
$tax = Tax::all('fl_tax_id','fl_tax_type','fl_tax_name','fl_charge_type','fl_charge_rate')->where('deleted_at' , '=', null);
return $tax;
}
Case 4
If I add one more column deleted_At in case 3 it's give me expected output.
public function index()
{
$tax = Tax::all('fl_tax_id','fl_tax_type','fl_tax_name','fl_charge_type','fl_charge_rate', 'deleted_at')->where('deleted_at' , '=', null);
return $tax;
}
What I want is I want only those record which is not soft deleted and from those records I want to select columns. How ?
UPDATE WITH MODEL AND CONTROLLER FILES
Tax.php (Model) - here BaseModel extends Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tax extends BaseModel
{
protected $table = 'tr_fl_tax_charges';
protected $primaryKey = 'fl_tax_id';
use SoftDeletes;
protected $softDelete = true;
//protected $fillable = ['fl_tax_type' , 'fl_tax_name' , 'fl_charge_type' , 'fl_charge_rate'];
protected $guarded = [];
protected $dates = ['deleted_at'];
}
TaxController.php
<?php
namespace App\Http\Controllers;
use App\Models\Tax;
use Illuminate\Http\Request;
use Validator;
class TaxController extends Controller
{
public function index()
{
$tax = Tax::all();
return $tax;
}
You need to remove the protected $softDelete = true; only leave the use SoftDeletes; will be OK.
With the current information provided, there is no reason that Case 1 should fail. Soft deletes work with the all() method, and I don't see any other issues in the currently provided code that would change that. I will update this answer if more code is provided that reveals the issue.
Case 2 "works" because you're actually calling where() on the Collection of all your Tax records. Tax::all() queries the database and builds a Collection of all the results, and then you're using where() to filter out the results with a null deleted_at field. This is highly inefficient.
Case 3 fails because your select list doesn't contain the deleted_at field. So, when you call where() on the Collection to only see the records where delete_at is null, all records will match since deleted_at doesn't exist. This is still calling where() on the Collection, not adding a where clause to the query, so it is inefficient.
Case 4 "works" again because you added the deleted_at field back in, so it will be in the Collection results, and the filtering can filter out the records where deleted_at is not null. But again, this is filtering the Collection of all your Tax records PHP side, not adding a where condition to your SQL query.
You should try this:
Change your Tax model and try:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tax extends BaseModel
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $table = 'tr_fl_tax_charges';
protected $guarded = ['fl_tax_id','_token'];
}
I am new to Laravel and am struggling with this:
Database - MSSQL existing DB schema cannot be modified as other software depends on it. (not sure if this is a problem or not)
Model/Table setup:
INFO_ALL Table - ID is primary key
PERSON Table - ID is foriegn key
ID's are hex values and I notice eloquent removes the 0x from the start of the value and am not sure if this is causing the relationship to fail or not. example: in the DB I see 0x123456789 in my returned eloquent data I see 123456789
Person Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
protected $table = 'PERSON';
protected $primaryKey = 'ID';
public $incrementing = false;
public $timestamps = false;
public function info_all(){
return $this->belongsTo(Info_All::class, 'ID', 'ID');
}
}
Info Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Info_All extends Model
{
protected $table = 'INFO_ALL';
protected $primaryKey = 'ID';
public $incrementing = false;
public $timestamps = false;
public function person(){
return $this->hasOne(Person::class, 'ID', 'ID');
}
}
How I am testing the relationship:
php artisan tinker
$person = App\Person::first();
$person->info;
NULL
php artisan tinker
$info= App\Info::first();
$info->person;
NULL
I know this relationship exists in the DB and I can manuualy get them together with a query but the relationship feature of this framework would really be nice to get figured out.
Beign new to Laravel there are a few things I am unsure about, like if the third argument in the realationship is neccesary since I am declaring the $primaryKey. I declared the $primarykey in the first model because I assummed it is case sensative and my table has ID not id. That being said, I have been stuck on this for a couple days and feel like I have tested everything in every different combination.
Any help is appreciated.
Your relation is defined incorrectly. Try by adding following relation:
Person Model
public function info()
{
return $this->hasOne(Info_All::class, 'ID', 'ID');
}
Info_All model
public function person()
{
return $this->belongsTo(Person::class, 'ID', 'ID');
}
Then try it out in tinker:
$person = App\Person::first();
$person->info;
I am not sure but if eloquent removes the 0x from the start of the value then it can also cause the problem.
Try by removing 0x from your tables.