Laravel Query Builder in Model - laravel

I would like to know if is it possible to work in a model using query builder to make a join between 4 tables, I don't know how to use eloquent with 4 tables
this is in controller
$kurikulum = DB::table('siakad.tb_01')
->select('siakad.tb_01.*', 'siakad.krs_jadwal_aktiv.*', 'siakad.mata_kuliah.*', 'siakad.kurikulum_item.*', )
->join('siakad.krs_jadwal_aktiv', 'siakad.tb_01.staf_id', '=', 'siakad.krs_jadwal_aktiv.kdds')
->join('siakad.mata_kuliah', 'siakad.krs_jadwal_aktiv.kdmk', '=', 'siakad.mata_kuliah.kode')
->join('siakad.kurikulum_item', 'siakad.mata_kuliah.id', '=', 'siakad.kurikulum_item.mata_kuliah_id')
->get();

Please try this:
$kurikulum = DB::table('tb_01')
->select('tb_01.*', 'krs_jadwal_aktiv.*', 'mata_kuliah.*', 'kurikulum_item.*')
->join('krs_jadwal_aktiv', 'tb_01.staf_id','krs_jadwal_aktiv.kdds')
->join('mata_kuliah', 'krs_jadwal_aktiv.kdmk','mata_kuliah.kode')
->join('kurikulum_item', 'mata_kuliah.id','kurikulum_item.mata_kuliah_id')
->get();

Related

how to convert Query Builder to Elequent query?

I have code from query builder I want to convert to eloquent but it doesn't work
my query builder code
$topkabupatens = DB::table('sekolahs as S')
->select('K.name', DB::raw('count(S.kabupaten) as jumlah_kabupaten'))
->join('kabupaten_kotas as K', 'S.kabupaten', '=', 'K.id')>orderBy('jumlah_kabupaten', 'DESC')->groupBy('K.name')->limit(10)->get();
my query builder code
$topkabupatens = Sekolah::with('kabupaten')->withCount('kabupaten')>orderBy('kabupaten_count', 'DESC')->groupBy('name')->limit(10)->get();
where is my mistake?
my query builder code runs but not with eloquent
try with
$topkabupatens = Sekolah::select('kabupaten_kotas.name')->withCount('kabupaten_kotas.kabupaten')
->leftjoin('kabupaten_kotas', 'Sekolah.kabupaten', '=', 'kabupaten_kotas.id')
->orderBy('kabupaten_count', 'DESC')
->groupBy('name')
->limit(10)
->get();

Join table with its model's default scope in Laravel

Currently, we can join 2 tables like
ModelA::join('table_b', 'table_a.id', '=', 'table_b.a_id');
With this approach the default scopes on model for table_b (ie: ModelB) are not applied on query. Suppose the ModelB has SoftDeletes enabled now the above join won't include whereRaw('table_b.deleted_at IS NULL'). I know i can manualy add this using following code.
ModelA::join('table_b', function($join) {
$join->on('table_a.id', '=', 'table_b.a_id')
->whereRaw('table_b.deleted_at IS NULL');
});
I want to know if there is any method to join so that it automatically apply default scope(s) in ModeB. Something like:
ModelA::joinModel(ModelB::Class, 'table_a.id', '=', 'table_b.a_id');
I used the joinSub() function to join on a subquery. So following code worked for me:
ModelA::joinSub(ModelB::select('*'), 'table_b', function($join) {
$join->on('table_a.id', '=', 'table_b.a_id');
});
By using joinSub() I can also call other scopes on ModelB like:
ModelA::joinSub(ModelB::filterThis()->filterThat(), 'table_b', function($join) {
$join->on('table_a.id', '=', 'table_b.a_id');
});
Filter out the records on related Model, the Eloquent way -
ModelA::with('modelb')->whereHas('modelb', function($query){
$query->filterThis()->filterThat();
})->get();
Laravel QueryBuilder doesn't consider Eloquent scopes while running queries.
You can simple use Eloquent instead of Query Builder. With Eloquent it can be achieved like so:
ModelA::with('modelb')->get();
Where modelb is a HasMany relationship defined in ModelA.
The above statement will produce the following query:
select * from `modela` where `modelb`.`modela_id` in (1) and `modelb`.`deleted_at` is null

Convert Query Builder to Eloquent Builder

I can not extract the result in groupby, the query builder below works very well but I want it to Eloquent.
I want to display only the folders that are already in the relationship?
how to convert a query builder to Eloquent?
$folders = Folder::select('folders.id','folders.title')
->join('matters', 'matters.folder_id', '=', 'folders.id')
->join('tutorials', 'tutorials.matter_id', '=', 'matters.id')
->whereDate('tutorials.start', '=', date('Y-m-d'))
->where('tutorials.status','=','0')
->groupby('folders.id')
->get();
It seems Floder hasMany Matter, Matter hasMany Tutorial.
You can create the hasManyThrough relationship in Folder Model, and use whereHas to find the folders
$folders = Folder::whereHas('tutorials', function($query) {
$query->whereDate('tutorials.start', '=', date('Y-m-d'))
->where('tutorials.status','=','0');
})->select('title', 'id')->get();
if you don't have hasManyThrough relationship, you can still get folders like this one:
$folders = Folder::whereHas('maters.tutorials', function($query) {
$query->whereDate('tutorials.start', '=', date('Y-m-d'))
->where('tutorials.status','=','0');
})->select('title', 'id')->get();

Trouble converting an SQL query to Eloquent

Trying to get this query to work in eloquent
A user can be in multiple teams however I want to generate a list of users NOT in a specific team. The following SQL query works if executed directly but would like to make it cleaner by converting it to eloquent
SELECT * FROM users LEFT JOIN team_members ON team_members.member_id = users.id WHERE NOT EXISTS ( SELECT * FROM team_members WHERE team_members.member_id = users.id AND team_members.team_id = $team_id )
This should provide a list of all the users that are not members of team $team_id
This is a guess ad you do not give much info on your Eloqent models but here is a hint of where to go:
User::doesnthave('teamMembers', function($builder) use($team_id){
return $builder->where('team_members.team_id');
});
That is assuming you have a "User" model with a "teamMembers" relationship setup on it
You may have a closer look in the Laravel docs for doesntHave
Laravel 5.8
Let's assume you have model name "User.php"
& there is method name "teamMembers" in it.
Basic
$users = User::doesntHave('teamMembers')->get();
Advance
use Illuminate\Database\Eloquent\Builder;
$users = User::whereDoesntHave('teamMembers', function (Builder $query) {
$query->where('id', '=', {your_value});
})->get();
You can find details description in this link >>
https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-absence
Laravel 5.2
Example:
DB::table('users')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
Check this link for advance where clause:
https://laravel.com/docs/5.2/queries#advanced-where-clauses
You can use below example
$list = User::leftJoin('users', 'users.id', '=', 'team_members.member_id')
->whereNotExists(function ($query) use ($team_id) {
$query->from('team_members')
->whereRaw('team_members.member_id = users.id')
->where('team_members.team_id', '=', $team_id);
})
->get();

Laravel elequent pivot table using where

How can I use Laravel to do something like this:
Tables:
projects:
id,name, active
pivot table: project_users
id, project_id, user_id
If I do this, I get good results, including all users of the project
Project::with('users')->where('active', '=', 1)->get();
But how can I filter on users and on active ? something like ?
Project::with('users')->where('active', '=', 1)->where('users',=,3)->get();
or ??
Project::with('users')->where('active', '=', 1)->where('users.user_id',=,3)->get();
If you want to restrict rows in the table you are eager loading then you can add constraints to the eager load where you can perform your usual QueryBuilder operations on the $query. So in your example we can do the following:
Project::with(['users' => function($query)
{
$query->where('user_id', '=', 3);
}])->where('active', '=', 1)->get();
This is assuming active is accessible to your initial table before the eager load.

Resources