php/laravel - select other table's column using the belongsToMany of laravel - php

This is my code on patient model:
class Patient extends Model
{
protected $primaryKey = 'PatientID';
public function users()
{
return $this->belongsToMany('App\Vaccine', 'immunizations', 'patient_id', 'vaccine_id');
}
}
and this is my query
$patients = Patient::whereDoesntHave('users', function ($q) use ($vaccine_id) {
$q->where('vaccine_id', '=', $vaccine_id);
})->get();
In my current situation I can only get the Patient model column data but not the other tables. Where should I put the select() method to select the rows and columns of the immunizations table because i want to set a chain where()or condition which is where('immunizations_id', 1) but it doesn't work because the immunizations table is not selected.
or does anyone here knows how to convert it without using a closure like make it
Patient::wheredoesnthave(join('table')); so i can freely manipulate it

We will get other relationship table using 'with()'
$patients = Patient::whereDoesntHave('users', function ($q) use ($vaccine_id) {
$q->where('vaccine_id', '=', $vaccine_id);
$q->with('Vaccine', 'immunizations');
})->get();
Try this.

Related

How to map using Laravel BelongsTo Relationship

I have a relationship between your_electricity_yesterday_category and building as building_id is present in your_electricity_yesterday_category table.
I am trying to get details out of the building table using the relationship.
I have this in my Electricity model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Electricity extends Model
{
use HasFactory;
protected $connection = 'mysql2';
protected $table = 'your_electricity_yesterday_category';
public function buildings()
{
return $this->belongsTo(Building::class, 'building_id');
}
}
I have this in my Repository
public function getAllBuilding()
{
// $buildings = Building::where('module_electricity', 1)->orderBy('description')->get();
$buildings = Electricity::with('buildings')->get();
return $buildings;
}
I have this in my controller
public function electBuilding()
{
$getBuilding = $this->electricityRepository->getAllBuilding();
return response()->json($getBuilding);
}
On the building table i have a column where module_electricity is either 0 or 1
How can i use this relationship to return building where module_electricity is 1 in json?
use whereHas query builder to filter parent Electricity details based on condition
$buildings = Electricity::with(['buildings'=>function($query){
$query->where('module_electricity',1);
}])
->whereHas('buildings',function($query){
$query->where('module_electricity',1);
})->get();
Also you can write scope for where condition in buildings model like below
public function scopeModuleElectricity($query,$module){
return $query->where('module_electricity',$module);
}
so your query will be
$buildings = Electricity::with(['buildings'=>function($query){
$query->moduleElectricity(1);
}])
->whereHas('buildings',function($query){
$query->moduleElectricity(1);
})->get();
Here is what I came up with:
public function getAllBuilding()
{
return Electricity::query()
->with('buildings', fn ($query) => $query->where('module_electricity', 1))
->get()
->pluck('buildings')
->collapse();
}
Walking through this step by step so you can better understand what's happening:
Initiating a query (completely optional, just for better code formatting)
Eager loading buildings with a condition (module_electricity = 1)
Retrieving data from the database
Extracting buildings only
Flat-mapping results
This will return a single collection with buildings that met a condition.
Let me know if the result turned out to be exactly what you expected.
P.S. Note that the above solution might not work if you're using older versions of PHP. If the above returns syntax error:
replace:
fn ($query) => $query->where('module_electricity', 1)
with:
function ($query) {
$query->where('module_electricity', 1)
}

Datatables: how to preserve id when sorting through a relation from another table (yajra, laravel)

I'm using datatables from yajra datatables and I have a problem.
I have a datatable where I obtain certain columns from other tables, for example the column "customer" is obtained through a relation from another table
But when I press the sort by customer button, the IDs change to the ID of the table where the relation belongs
This generates errors in the buttons that I have on the right since these IDs do not exist in the "meos" table, only in the "locations" table that is in the relation
How can I make it sort while keeping the same ID it had?
I want to always keep as order criteria the ID of the table I am with, which is the "meos" table belonging to the "meo" class
This is my query
public function query()
{
$languageId = Auth::user()->language_id;
return Meo::with(['businessType' => function ($query) use ($languageId) {
$query->with(['businessTypeDescriptions' => function ($subQuery) use ($languageId) {
$subQuery->where('language_id', '=', $languageId);
}]);
}])->with('location');
}
this is my function getcolumns
protected function getColumns()
{
return [
Column::make('id')->addClass('text-center')->title(__('digestReport.columns.id')),
Column::make('location.location_name')->addClass('text-center')->title(__('digestReport.columns.customer')),
Column::make('businessType')->addClass('text-center')->title(__('digestReport.columns.business_type'))->searchable(false),
Column::computed('action')->exportable(false)->printable(false)->width(160)->addClass('text-center')->title(__('digestReport.columns.actions')),
];
}
please, I need help.
Thanks :)
Try below code. Add ->select() statement
public function query()
{
$languageId = Auth::user()->language_id;
return Meo::with(['businessType' => function ($query) use ($languageId) {
$query->with(['businessTypeDescriptions' => function ($subQuery) use ($languageId) {
$subQuery->where('language_id', '=', $languageId);
}]);
}])->with('location')->select('meo-table.*');
}
Replace meo-table with your database table for Meo::class

laravel eloquent complex select inside where statement

halo, i have data and want to display it like picture below
there are two models relationship, Person and Installment.
this is Person model:
class Person extends Model
{
protected $table = 'person';
public function angsuran()
{
return $this->hasMany(Installment::class);
}
}
this is Installment model:
class Installment extends Model
{
protected $table = 'installment';
public function person()
{
return $this->belongsTo(Person::class);
}
}
and this is my controller to querying and display data
$data = Person::with('angsuran')
->whereHas('angsuran', function ($q) {
$q->whereBetween('installment_date', [\DB::raw('CURDATE()'), \DB::raw('CURDATE() + INTERVAL 7 DAY')])
->where('installment_date', '=', function () use ($q) {
$q->select('installment_date')
->where('status', 'UNPAID')
->orderBy('installment_date', 'ASC')
->first();
});
});
return $data->get();
it show error unknow colum person.id in where clause
please help. thanks.
As the comment said, you need to put $q as a parameter to the Closure.
When using subqueries, it's useful to tell the query builder which table it is supposed to query from.
I've rewritten your query. It should achieve what you're looking for. Also, changed the CURDATE to Carbon objects.
today() returns a datetime to today at 00:00:00 hours. If you need the hours, minutes and seconds, replace today() by now().
$data = Person::with('angsuran')
->whereHas('angsuran', function ($subquery1) {
$subquery1->where('installment_date', function ($subquery2) {
$subquery2->from('installment')
->select('created_at')
->where('status', 'UNPAID')
->whereBetween('installment_date', [today(), today()->addWeeks(1)])
->orderBy('installment_date')
->limit(1);
});
});
Using with and whereHas you will end up with two query even if you have limit(1) in your subQuery and the result will show all 4 installment related to the person model. also I don't think you can order on the subquery, it should be before the ->get
so here's i've rewritten your code
$callback = function($query) {
$query->whereBetween('installment_date', [today(), today()->addDays(7)])
->where('status', 'UNPAID')
->orderBy('installment_date');
};
$data = Person::whereHas('angsuran', $callback)->with(['angsuran' => $callback])->get();
or you can use query scope. please see this answer Merge 'with' and 'whereHas' in Laravel 5

Laravel Join Using Eloquent Relations

I have four models created, and their relations have been defined correctly. What I haven't grasped is how to use those relations for my situation.
Let's use countries > regions > cities > censuses as a contrived example of the relations. I can get the most recent date a census was taken on with this function in the Census model:
public static function getMaxTakenOn($country_id)
{
return \DB::table('regions')
->join('cities', 'cities.region_id', '=', 'region.id')
->join('censuses', 'censuses.city_id', '=', 'cities.id')
->where('regions.country_id', '=', $country_id)
->max('censuses.taken_on');
}
How would I rewrite the function body to use the Eloquent Relations?
Using the hasMany and a custom field in each of the models:
https://laravel.com/docs/5.5/eloquent-relationships
Example in your Regions model, you will need a:
public function cities() {
return $this->hasMany('App\Cities');
}
Then so on in your other models.
Once that is done, you don't need the 2 joins, you can access them like:
$region = new Region();
$region->where('country_id', '=', $country_id)
->max('censuses.taken_on');
echo $region->cities()->censuses()->count();

Laravel querying multiple related models

For example: I have these models in my application.
User, Profile, Interest.
I linked the users table with the profiles table by adding the user_id column in the profiles table. And I linked profiles and interests by using a pivot table (interest_profile), Which is (as obvious) will have two columns (profile_id, interest_id).
However, I want to query the users who are associated with a profile, too see who is associated with a particular interest, In other words: "select all users who are having (in their profiles) that particular interest".
I know that I can do this with raw SQL by joining the four tables and then use (where clause).. But I want to do it the Laravel way.
Thanks in advance.
First make sure you have your relationships setup correctly on your models like:
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
class Profile extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function interests()
{
return $this->belongsToMany(Interest::class, 'interest_profile');
}
}
class Interest extends Model
{
public function profiles()
{
return $this->belongsToMany(Profile::class, 'interest_profile');
}
}
Then you can use whereHas() to constrain a query by a related model and dot notation for nested relations. So your query would be:
User::whereHas('profile.interests', function($query) use ($interestName) {
return $query->where('name', $interestName);
})->get();
That would just return a collection of users. If you wanted to return their profiles and interests as well you would use with():
User::whereHas('profile.interests', function($query) use ($interestName) {
return $query->where('name', $interestName);
})
->with('profile.interests')
->get();
Assuming the User model has a relationship profile and the Profile model has a relationship interests, you can do this.
$interest_id = 1;
$users = User::whereHas('profile', function ($query) use ($interest_id) {
$query->whereHas('interests', function ($query) use ($interest_id) {
$query->where('id', $interest_id);
});
})->get();

Categories