How write pivot table with name of column in whereBetween condition? - laravel

I have relation contain pivot table and when I run code appear this problem
Column not found: 1054 Unknown column 'guest_show.show_date' in 'where clause' (SQL: select * from guests where guest_fname is null and guest_show.show_date between 05/20/2018 and 05/20/2018).
what is solve?
This is my model and function
class Guest extends Model
{
protected $primaryKey = 'guest_id';
protected $table = 'guests';
protected $fillable =
['guest_fname','guest_lname','profession','mobile','work_phone',
'current_job','previous_job','work_address','DOB','DD'];
public function programs()
{
return $this->belongsToMany(Program::class, 'guest_show', 'guest_id',
'program_id')
->withPivot('subject', 'show_date');
}
public function specialties()
{
return $this->belongsToMany(Specialization::class, 'guest_speciality',
'guest_id', 'speciality_id');
}
public static function filter()
{
// Search for a guest based on their name.
$guests=Guest::with('programs', 'specialties');
if (request()->has('guest_fname')) {
$guests->where('guest_fname', request()->input('guest_fname'));
}
// Search for a guest based on their programs.
if (request()->has('program_name')) {
$guests->where('program_name', request()->input('program_name'));
}
// Search for a guest based on their specialties.
if (request()->has('specialty_name')) {
$guests->where('specialty_name', request()-
>input('specialty_name'));
}
// Search for a guest based on their date.
$datefrom=request()->input('from');
$dateto = request()->input('to');
if (request()->has('from') || request()->has('to')) {
$guests->whereBetween('guest_show.show_date', [$datefrom, $dateto]);
}
return $guests->get();
}

Try in closure.
$guests=Guest::with('programs' => function($query) use ($datefrom,$dateto){
$query->whereBetween('guest_show.show_date', [$datefrom, $dateto]); })
, 'specialties');
P.S : I modified only the where between method.

Related

Search Query by Child field Eloquent relation

My Product Model is
public function IncomeRepo(){
return $this->hasMany(Income::class,'Product');
}
My Income Report Model Is
public function ProductData(){
return $this->belongsTo(Product::class,'Product','id');
}
My Query is
public function SearchIncomeData(Request $request){
$GetFromDate = $request->FromDate;
$GetToDate = $request->ToDate;
$ProductData = Product::with('IncomeRepo')->whereBetween('created_at', [$GetFromDate, $GetToDate])->get();
return view('Admin.Report.ProductSalesReport',compact('ProductData'));
}
When I return $ProductData it return products table created_at Data. BUT I nee Income table created_at data which be multiple
How can I get it?
My expectation show incomes table created_at data
If you want to filter data by child tables date then you need to use whereHas relationship.
$GetFromDate = $request->FromDate;
$GetToDate = $request->ToDate;
$ProductData = Product::with('IncomeRepo')
->whereHas('IncomeRepo',function($que) use($GetFromDate,$GetToDate) {
$que->whereBetween('created_at',[$GetFromDate, $GetToDate])})->get();
return view('Admin.Report.ProductSalesReport',compact('ProductData'));
In controller. (Use whereBetween)
public function SearchIncomeData(Request $request)
{
$GetFromDate = $request->FromDate;
$GetToDate = $request->ToDate;
$ProductData = Product::with(['IncomeRepo' => function ($query) use ($GetFromDate, $GetToDate)
{
$query->whereBetween('created_at', [$GetFromDate, $GetToDate]);
}
])->get();
return view('Admin.Report.ProductSalesReport', compact('ProductData'));
}
In view
foreach ($ProductData as $product)
{
foreach ($product->IncomeRepo as $income)
{
echo $income->created_at;
}
}

Laravel Eager loading ,relationship in builder be a value directly

it's a row with another row, condition on id to info_status
relationship
public function status(){
return $this->hasOne(Row::class,'id','info_status')->select("id" ,"row")
}
result
Row::with('status')->find(5588)
=> App\Models\Row {#3563
id: 5588,
info_status: "2637",
status: App\Models\Row {#3576
id: 2637,
row: 1104,
},
}
how to get status->row->value ,become status->value at preloading sql builder ?
Is it possible ? doc didn't mention it.
//expect
=> App\Models\Row {#3563
id: 5588,
info_status: "2637",
status: 1104,
},
}
Assuming table name as rows, here is my solution:
$row = \Illuminate\Support\Facades\DB::table('rows')
->join('rows as related_rows', 'rows.info_status', 'related_rows.id')
->select('related_rows.row as status', 'rows.id', 'rows.info_status')
->get();
You'll need to make use of an accessor.
The accessor retrieves the row value from the relationship and returns it as an attribute.
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
class Row extends Model {
public $appends = ['status'];
//Relationship status
public function statusRow(){
return $this->hasOne(Row::class,'id','info_status');
}
/**
* Accessor to create status attribute and retrieve row value
* #return \Illuminate\Database\Eloquent\Casts\Attribute
*/
*/
public function getStatusAttribute() : Attribute
{
return Attribute::make(
get: fn () => $this?->statusRow->row;
);
}
}
Source: https://laravel.com/docs/9.x/eloquent-mutators#defining-an-accessor

Laravel - for some reason, max breaks my query

I have this piece of code:
$query = Student::whereHas('statusuri', function($q) use ($status) {
$q->latest('status_student.id')->take(1)
->where('status_id', $status)
->whereNotNull('status_id');
});
and it works fine, but I don't necessarily get the desired result.
I tried changing the first line to max (so I don't filter all my records then do a limit 1), I just get the highest ID from the beginning - like this:
$query = Student::whereHas('statusuri', function($q) use ($status) {
$q->max('status_student.id')
->where('status_id', $status)
->whereNotNull('status_id');
});
but then my query breaks.
For some reason, I get this:
Unknown column 'students.id' in 'where clause' (SQL: select max(`status_student`.`id`) as aggregate from `statusuri` inner join `status_student` on `statusuri`.`id` = `status_student`.`status_id` where `students`.`id` = `status_student`.`student_id`)
Why does my query break after I do this change?
Thanks.
Tables:
students
id bigint(20)
//other non-related data
statusuri
id bigint(20)
nume VARCHAR(255)
status_student
id int(11)
student_id int(10)
status_id int(10)
stare_stagiu_id int(11)
created_at timestamp
updated_at timestamp
statusuri() from Student
public function statusuri()
{
return $this->belongsToMany(Status::class, 'status_student')
->withPivot('id', 'data_inceput', 'data_sfarsit', 'document', 'status_id', 'stare_stagiu_id')
->withTimestamps();
}
Status and StatusStudent classes
class StatusStudent extends Model
{
protected $table = 'status_student';
protected $fillable = ['id', 'student_id', 'status_id', 'stare_stagiu_id'];
}
class Status extends Model
{
protected $table = 'statusuri';
public $fillable = ['nume'];
}
Your relations are messed up. The query is trying to use a column from the student table, but the student table is not available in said query as it is not joined. See this fiddle to see what goes wrong in the SQL.
http://sqlfiddle.com/#!9/52c96fa/6
In the end, I'd do it like this if I understood you correctly:
In StatusStudent.php (Model):
public function student() {
return $this->hasOne(Student::class, 'id', 'student_id');
}
In Controller:
public function stackoverflowtest() {
//Set teststatus
$status = 1;
//Get the latest status of all users - and if that status is correct, retrieve into array
$latest = DB::select( DB::raw("SELECT max(id) as id, student_id FROM status_student group by student_id"));
$array = [];
foreach ($latest as $l) {
$status_id = StatusStudent::whereId($l->id)->whereStatusId($status)->first();
if ($status_id) {
array_push($array, $status_id);
}
}
//$array now holds all the StatusStudent, simply user ->student to get the student related to said status, example below
if($array) {
dd($array[0]->student);
return $array;
} else {
return 'No match';
}
}
First, we get all latest records for each user IF the status is correct. Then, we simply get the Student from the status_student table via the relation.

query scope with conditional constraint

When building a query, if one of the constraints does not return result only then run another constraint
public function scopeLatestLocationSchedule($query, $location)
{
return $query
->where('location_id', $location)
->whereNull('service_id')
->whereNull('end_date') //If not found null end_date then return latest first end_date
}
How to write this query with a conditional check on the end_date constraint
Write below code in your model
use Illuminate\Database\Eloquent\Builder;
class YourModelName extends Model
{
public function scopeEndDateNullLocationSchedule(Builder $builder, $locationId)
{
return $builder->where('location_id', $locationId)
->whereNull('service_id')
->whereNull('end_date');
}
public function scopeEndDateNotNullLocationSchedule(Builder $builder, $locationId)
{
return $builder->where('location_id', $locationId)
->whereNull('service_id')
->whereNotNull('end_date');
}
Write this below code in your controller
$locationId = 1; // put your location id here;
$query = YourModelName::endDateNullLocationSchedule($locationId);
if (!count($query->get())) {
$query = YourModelName::endDateNotNullLocationSchedule($locationId);
}
$locationSchedule = $query->orderBy('end_date', 'DESC')->first();
dd($locationSchedule);
When I have many conditions, I find ver useful to use this snippet before the Controller declaration (just under "use...")
Builder::macro('if', function ($condition, $column, $operator, $value){
if ($condition) {
return $this->where($column, $operator, $value);
}
return $this;
});
Then you can build your queries adding this kind of conditions:
->if($request->service_id, 'id', '=', $request->service_id)
the line above will trigger only if there is a value for service_id, in that case the select query will search where the id is like $request->service_id.
Hope it helps!

set manually id for row of table by JTable in joomla

i have table with field user_id (unique). i want set manually set it.but when i set it,JTable not insert data.
my $data array is:
$data['user_id']=500;
$data['name']='test';
$data['lastname']='test';
and my code in model is:
$table = $this->getTable();
if ($table->save($data) === true) {
return $table->user_id;}
and my table file is:
class UserproTableuser extends JTable
{
public function __construct(&$db)
{
parent::__construct('#__userpro_users', 'user_id', $db);
}
}
Try this:
$table->bind($data);
$table->save();

Resources