Sort eloquent model with eager loaded relationship in Laravel - laravel

I'm trying to build a small application where I am having three models, I want to sort the model by column inside the eager load relationship, for this I have a model named AssociatedCompany as:
class AssociateCompany extends Model {
protected $table = 'project_associate_company';
protected $fillable = [
'project_id', 'company_role_id', 'company_specialisation_id', 'company_id', 'link', 'file_name'
];
public function project()
{
return $this->belongsTo('App\Project','project_id','id');
}
public function companyRole()
{
return $this->belongsTo('App\Role', 'company_role_id','id');
}
}
and other model Role as :
class Role extends Model
{
protected $table='company_role';
protected $fillable = [
'sl', 'name', 'parent_id'
];
}
Now I want to fetch all the companies of related project and sort them out with sl of role, for this I am trying to do a join something like this:
$companies = Project\AssociateCompany::whereHas('project', function ($q) use($request) {
$q->where('slug', $request->slug);
})
->with('companyRole')
->join('company_role', 'project_associate_company.id', '=', 'company_role.project_associate_company_id')
->orderBy('company_role.sl', 'desc')
->paginate(20);
So in this I am getting an error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'company_role.project_associate_company_id' in 'on clause' (SQL: select count(*) as aggregate from project_associate_company inner join company_role on project_associate_company.id = company_role.project_associate_company_id where exists (select * from projects where project_associate_company.project_id = projects.id and slug = kovacek-rodriguez and projects.deleted_at is null) and project_associate_company.deleted_at is null)
Help me out in this.

Related

Laravel Eloquent query relations with 3 levels

I want some help of forming queries on Laravel Eloquent
I have 4 models in my application
Item Model
class Item extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'code', 'name', 'type', 'price', 'cost', 'reorder_level', 'status'
];
public function grnoteitems()
{
return $this->hasMany(Grnoteitem::class);
}
}
Grnote Model
class Grnote extends Model
{
use HasFactory;
protected $fillable = [
'date', 'number', 'warehouse_id','user_id', 'authorized_id', 'approved_id', 'notes'
];
public function grnoteitems()
{
return $this->hasMany(Grnoteitem::class);
}
public function warehouse()
{
return $this->belongsTo(Warehouse::class);
}
}
Grnoteitem Model
class Grnoteitem extends Model
{
use HasFactory;
protected $fillable = [
'grnote_id', 'item_id', 'description', 'packing', 'quantity', 'price', 'total'
];
public function grnote()
{
return $this->belongsTo(Grnote::class);
}
public function item()
{
return $this->belongsTo(Item::class);
}
}
Warehouse Model
class Warehouse extends Model
{
use HasFactory;
protected $fillable = ['name', 'address'];
public function grnotes()
{
return $this->hasMany(Grnote::class);
}
}
Quantity of the item is calculated by multiplying quantity and packing columns in the grnotes table.
Now I want to retrieve all the items with their quantity(quantity * packing) from a particular warehouse.
I tired the below query
$items = Item::withSum('grnoteitems', 'quantity', function($query) use($warehouse, $from, $to){
$query->with('grnote', function($query1) use($warehouse, $from, $to){
$query1->where('warehouse_id', $warehouse->id)
->whereBetween('date', [$from, $to])->get();
})->get();
})->get();
This is working fine. But I don't find any way to get sum of two multiplied columns
I want something like
$items = Item::withSum('grnoteitems', '(quantity * packing)', function($query) use($warehouse, $from, $to){
$query->with('grnote', function($query1) use($warehouse, $from, $to){
$query1->where('warehouse_id', $warehouse->id)
->whereBetween('date', [$from, $to])->get();
})->get();
})->get();
Please help me to solve this.
It's a bit long to write all the code to do this, but my idea would to :
start your query from the wareHouse you want items from
so Warehouse::first() [with grnote [with item]] and custom where stuff
then the data you need to calculate are on the pivot table between Item and Grnote, so I would add withPivot to both relations
in this query order, the pivot value will be appended as a relation to the Item object
I would add a new attribute to the item model. Checking if the pivot attribute is set (so it comes from a query with pivot), calculate the quantity, and append it to the Item instance
You can also loop on the resulting Collection to append your new attribute.

Syntax error or access violation: 1066 Not unique table/alias: '

I am writing an app in laravel which displays this error SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'medicals' (SQL: select * from patients left join medicals on medicals.patients_id = patients.id left join medicals on medicals.trx_id = patient_referral.trx_id)
return Patients::where(function ($q) use ($startdate, $enddate, $id) {
$q->where("patient_referral.trx_id", $id);
})
->leftJoin("medicals", "medicals.patients_id", "=", "patients.id")
->leftJoin("medicals", "medicals.trx_id", "=", "patient_referral.trx_id")
->get();
Medical Model
class Medicals extends Model
{
protected $guarded = [];
public function patients()
{
return $this->belongsTo(Patients::class, "id", "patients_id");
}
public function tests()
{
return $this->belongsTo(Tests::class);
}
}
Patient Model
class Patients extends Model
{
protected $guarded = [];
public function medicals()
{
return $this->hasMany(Medicals::class);
}
public function patient_referral()
{
return $this->hasMany(PatientReferral::class);
}
}
Patient Referral Model
class PatientReferral extends Model
{
protected $guarded = [];
protected $table = "patient_referral";
public function patients()
{
return $this->belongsTo(Patients::class);
}
}
You are trying to join medicals table twice so in this case you need to provide unique alias to each instance and in join clause specify that alias for columns so that database will know the exact column from table to use in filter like
Patients::where(function ($q) use ($startdate, $enddate, $id) {
$q->where("patient_referral.trx_id", $id);
})
->leftJoin("medicals as a", "a.patients_id", "=", "patients.id")
->leftJoin("medicals as b", "b.trx_id", "=", "patient_referral.trx_id")
->get();

How to fix laravel eloquent many to many relation insertion error on wrong table

I have a model class with the name CourseSession and it's table is course_session, and I have another model named Student and it's table is student and every session has many students and also every student could be in many sessions. So I have created a third table named student_session with student_id, session_id, presence and laravels timestamp columns.
Creating a session needs to have a list of students and I get them from $request like this:
$validatedData = $request->validate([
'students' => 'required',
]);
students is array of students id!
this is my CourseSession model:
class CourseSession extends Model
{
protected $table = 'course_sessions';
protected $guarded = [];
public function course()
{
return $this->belongsTo('App\Course');
}
public function students()
{
return $this->belongsToMany('App\Student', 'student_session','session_id', 'student_id');
}
}
and this is my student model:
class Student extends Model
{
protected $guarded = [];
public function courses()
{
return $this->belongsToMany('App\Course');
}
public function exams()
{
return $this->belongsToMany('App\Exam');
}
public function sessions()
{
return $this->belongsToMany('App\CourseSession', 'student_session', 'student_id', 'session_id');
}
}
I create a session like this:
$session = new CourseSession();
$session->course_id = $course->id;
$session->save();
and I save students this way:
$sessions = $session->students()->create(['session_id' => $session->id, 'student_id' => 1, 'presence' => 1]);
but I get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'session_id' in 'field list' (SQL: insert into `students` (`session_id`, `student_id`, `presence`, `updated_at`, `created_at`) values (25, 1, 1, 2019-04-28 14:24:48, 2019-04-28 14:24:48))
according to error, it tries to write data on students table but I want to write them on student_session table!
what is wrong in my codes?
For this you want to use attach() instead of create().
$session->students()->attach(1, ['presence' => 1]);
In the above example 1 is the student_id. You don't need to specify the session_id as your calling this from a Session model. The array at the end is any additional data you want to add to the pivot table.
Since you have additional data in your student_session pivot table, it might also be an idea to add this to your belongsToMany relationships e.g.
public function sessions()
{
return $this->belongsToMany('App\CourseSession', 'student_session', 'student_id', 'session_id')
->withPivot('presence')
->withTimestamps();
}
This will include the presence and timestamps columns in the pivot data as well (obviously, you don't have to do this if you don't want to though).

(laravel4) pulling data from pivot table

I tried to refrain myself from asking a stupid question once again, but here i am...
So i want to check if a ID in my pivot table (tutorial_id) matches another id. However, i have no idea how to to get this ID from the pivot table.. this is what i tried:
Controller:
class TagController extends BaseController {
public function getTutorials($tag) {
$tag_id = Tag::where('name', $tag)->first();
$tutorials = Tutorial::with('tags')->where('tutorial_id', '=', $tag_id->id)->get();
return View::make('tutorials/tags', array(
'tutorials' => $tutorials
));
}
}
Tutorial model:
class Tutorial extends Eloquent {
protected $table = 'tutorials';
public function tags() {
return $this->belongsToMany('Tag', 'tutorials_tags', 'tutorial_id');
}
}
Tag model:
class Tag extends Eloquent {
protected $table = 'tags';
public function tutorials() {
return $this->belongsToMany('Tutorial', 'tutorials_tags', 'tag_id');
}
}
Database looks like this:
However i now get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'tutorial_id' in 'where clause' (SQL: select * from `tutorials` where `tutorial_id` = 1)
So you want all tutorials with tag_id->id, you can do that like this: $tag_id->tutorials
I reformatted the code for you:
public function getTutorials($tag) {
$tag = Tag::where('name', $tag)->first();
return View::make('tutorials/tags', array(
'tutorials' => $tag->tutorials
));
}
reference: http://vegibit.com/many-to-many-relationships-in-laravel/

How to use Eager Loading and Join in Eloquent at a same time in laravel 4

Models
class WPModel extends Eloquent
{
protected $table = 'work_processes';
protected $guarded = array('id');
protected $softDelete = true;
// declaring one-to-many relationship
public function relatedWPAQs()
{
return $this->hasMany('WPAQModel', 'wp_id');
}
public function relatedUsers()
{
return $this->belongsTo('UserModel', 'wp_owner_id');
}
}
class UserModel extends Eloquent
{
protected $table = 'users';
protected $softDelete = true;
public function relatedWPs()
{
return $this->hasMany('WPModel', 'wp_owner_id');
}
}
class WPAQModel extends Eloquent
{
protected $table = 'wp_audit_questions';
protected $fillable = array('wp_id', 'wp_audit_question');
// declaring one-to-many relationship - the inverse way
public function relatedWP()
{
return $this->belongsTo('WPModel', 'wp_id');
}
public function scopeWpParent($query, $id)
{
return $query->where('wp_id', '=' ,$id);
}
}
Controller
class WPAQController extends BaseController
{
public function showWPAQ($wpid)
{
$workprocess = WPModel::where('id', $wpid)
->join('users', 'users.id', '=', 'work_processes.wp_owner_id')
->select('users.user_name', 'work_processes.*')
->with(array(
'relatedWPAQs' => function($query) use ($wpid)
{
$query->where('wp_id', '=',$wpid);
}
))
->get();
return View::make('wpaqshow')->with(compact('workprocess'));
}
}
when I run this code, I get following error
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in
where clause is ambiguous (SQL: select users.user_name,
work_processes.* from work_processes inner join users on
users.id = work_processes.wp_owner_id where
work_processes.deleted_at is null and id = ?) (Bindings: array (
0 => '1', ))
Try the following:
$workprocess = WPModel::where('work_processes.id', $wpid)
->join('users', 'users.id', '=', 'work_processes.wp_owner_id')
->select('users.user_name', 'work_processes.*')
->with(array(
'relatedWPAQs' => function($query) use ($wpid)
{
$query->where('wp_id', '=',$wpid);
}
))
->get();
You have joined few tables. Now laravel has many Ids. You have to tell Laravel which id in where clause Laravel should use..
WPModel::where('id', $wpid)

Resources