How to get data from Multiple Tables with Laravel Eloquent - mysql

I have 2 tables called jobs & job_records. Its relationship as below:
JobRecords Model
public function job()
{
return $this->belongsTo(Job::class);
}
Job Model:
public function jobRecord()
{
return $this->hasOne(JobRecord::class);
}
jobs table has 2 columns that I need to display alongside my job_records table view. It's total_pges & status.
In my JobRecords Controller, I have tried the following method. It throws me an error of Call to undefined relationship.
JobRecordController:
$job_records = JobRecord::whereStatus('In Progress')
->with('jobs', 'jobs.status', 'jobs.total_pges')
->get();
return DataTables::of($job_records)
I am still beginning with Laravel and PHP. I can sense that there is something wrong with the relationship. But I couldn't figure out what it is exactly. Can anyone help me out with this matter?

In your JobRecord model change the relation ship as
public function job()
{
return $this->hasOne('App\Models\Job','foreign_key','local_key');
}
Similarly, in Job model
public function job()
{
return $this->belongsTo('App\Models\JobRecord','foreign_key','local_key');
}
Replace foreign_key and local_key with appropriate values...

I deleted my previous answer. What are you trying to do exactly? You can't use "jobs" in the "with function" without to define "jobs" as function in the model.
If you change it to "job" (instead of "jobs), then it would work, but I don't know if you want this. With your query you saying that a record have many jobs? But your model doesn't define that.

Related

How to make query according to my problem in Laravel 8?

Image drive link: Click
My database looks like the photos. Now I need a query result that i describe in two step for better understandind.
step 01: I need these result where syllab_subjects have a specific syllab id. $query_step1 = SyllabSubject::where('syllab_id',$given_id)->get()
step 02: I need only these subject which is not exist in $query_step1. Simply, In $query_step1 check which subject_id is not available when compare with subject table.
For better understanding, if we make query for syllab_id 10, then query result returns "science" and if syllab_id 5 then it returns "English and Science"
Have you set up models with relationships for these tables? It looks like you haven't. What you need is a model like
class Subject extends Model
{
public function syllab() {
return $this->hasMany(Syllab::class):
}
}
and
class Syllab extends Model
{
public function subject(){
return $this->belongsTo(Subject::class);
}
}
Then you can get the details like
$syllab = Syllab::find(10);
$syllab->subjects->pluck('name');

Laravel accessor relationship

I have relationship batch and project
function project(){
return $this->hasMany(Project::class,'batch_id');
}
I need to get which batch is complete based on all projects (status = COMPLETED) as a Laravel accessor in model.
this is my sample data
please help. thanks!
You need to change the code from
function project(){
return $this->hasMany(Project::class,'batch_id');
}
to
function project(){
return $this->hasMany(Project::class,'project_id');
}
to get the completed batch
$batch=Project::where('status','COMPLETED')->pluck('batch_id');
In the Relationship
You can add the where inline on the relationship
function project(){
return $this->hasMany(Project::class,"bacth_id")->where("status","COMPLETED");
}
When Invoking the Relationship
If you want to keep the relationship without the where and only use it sometimes, you can call the relationship and add the where. for example, if you have an instance of your model (im going to call it $model in this example) you can do the following, notice the parenthesis next to the relationship name:
$completed = $model->project()->where("status","COMPLETED")->get();
In a Query
If you are writing a query where you are trying to pull in only versions of that model where the project is complete you can use the whereHas function. as i dont know what your model is called in your example, im just gonna call it Model
$posts = Model::whereHas("project", function (Builder $query) {
$query->where("status","COMPLETED");
})->get();

Laravel belongs to (more than 1 table)

has a rookie in laravel i don't no very well where and how to do this.
I have 3 tables that have almost the same fields, but they all have in comon ID
public function book(){
return $this->belongsTo('App\Models\table1', 'book_id', 'id');
}
this works but can i do something like this??
What should i use?
public function book(){
return $this->belongsTo('App\Models\table1','App\Models\table2', 'book_id', 'id');
}
Thanks for sharing your knowlege.
You may define 2 separate belongsTo functions
//...
public function book(){
return $this->belongsTo('App\Book', 'foreign_key', 'primary_key');
}
public function author(){
return $this->belongsTo('App\Author', 'foreign_key', 'primary_key');
}
//...
No, you can't create a single relationship with two tables in that way, that's not the way Laravel reads the method.
It would be pretty easy, and likely most clear for code readability to just make two separate relationships:
public function book(){
return $this->belongsTo('App\Models\table1', 'foreign_key');
}
public function otherBook(){
return $this->belongsTo('App\Models\table2', 'foreign_key');
}
But, it may be worth your time to consider the overall architecture of your models and tables first. If these tables share a common ID, that's going to get quite confusing over time, and carry a lot of overhead to make sure you don't over-write. Why not just make one table with some kind of flag to identify the different types of book?
Hope this helps.

Eloquent query problem using with() function for model relationship eager loading

How do write this eloquent query in Laravel so that it eager loads with() the relationship model in this example between a User model and Profile model? I was trying to avoid 2 separate queries.
I feel I am close, but somethings not quite right.
$author = User::where('id', $id)->with('profile')->get();
The collection is returning the user details correctly. But it's showing the profile relationship as null.
#relations: array:1 [▼
"profile" => null
]
I believe I have things setup correctly with a User model and a Profile needed relationships.
User.php
public function profile()
{
return $this->hasOne('App\AuthorProfile', 'user_id');
}
AuthorProfile.php
public function user()
{
return $this->belongsTo('App\User');
}
Assuming for AuthorProfile model table you have record with id of user it should be fine.
However you wrote:
I was trying to avoid 2 separate queries.
Well, it's not true, if you have single record, eager loading won't help you at all. In this case 2 queries will be execute - no matter if you use eager loading or you won't.
Eager loading would help if you had multiple users and for each of them you wanted to load profile, but if you have single record it won't change anything.
Additionally instead of:
$author = User::where('id', $id)->with('profile')->get();
you should rather use:
$author = User::with('profile')->find($id);
because you expect here single user.
$users = User::with('profile')->find($id);
Your model should be like this.The User_id on the profile table and id on the user table
public function profile()
{
return $this->hasOne('App\AuthorProfile', 'user_id','id');
}

Add WHERE condition to all SQL requests in Laravel

I'm creating an online tool for companies that each have a set of users in Laravel.
When a user is connected, he has a $connected_company_id variable
For every SELECT request (called by ::all(), find(), ...), i would like to add the condition: where company_id = $connected_company_id. I have found this post: laravel set an automatic where clause, but it doesn't work by overriding newQuery().
For every INSERT request, i would like to add the company_id.
Is this possible without changing my code inside all the controllers ?
I thought about extending Eloquent with customEloquent, and then make my models extend customEloquent, but I don't know how to write the code for customEloquent and if it could work.
Well, you could make use of the Eloquent Model Events. I assume you have the connected_company_id stored in the Session company_id
class BaseModel extends Eloquent{
public static function boot(){
parent::boot();
//Column to inject when inserting
static::creating(function ($obj){
$obj->company_id = Session::get('company_id');
});
//Column to inject when updating
static::updating(function ($obj){
$obj->company_id = Session::get('company_id');
});
}
}
You can extend the BaseModel class on all the models that you want the company_id to be inserted or updated. Take a look at Eloquent Model Events for more information.
The above code will automatically insert or update the company_id to the model that you extend the BaseModel to. When you do a Model::all() or Model::get(), you automatically get the company_id on that Model and you can also perform searches as you requested on Point `
Hope this helps.
well, you can just add the company id to the find query.
Model::where("company_id","=",$company_id):
Or you can create a scope:
class theModel extends Eloquent {
static $company_id;
static for_company($company_id){
self::company_id=$company_id;
return __CLASS__;
}
public function scopeCompany($query)
{
return $query->where('company_id', '=', self::company_id);
}
}
//And later
$scope=theModel::for_company($company_id);
$res=$scope::company->where(...);
Disclaimer: I haven't tried this. Just a solution I constructed. Let me know if this works. This will not work under PHP 5.3