Laravel filtering query results with relations - laravel

I have this relations
and defined models for all 3 tables
class Employee extends Model
{
use HasFactory;
protected $table = 'employees';
public function departments()
{
return $this->belongsToMany(Department::class, 'dept_emp', 'emp_no', 'dept_no', 'emp_no', 'dept_no');
}
}
class Department extends Model
{
use HasFactory;
protected $table = 'departments';
}
class Dept_emp extends Model
{
use HasFactory;
protected $table = 'dept_emp';
}
And in my controller
$employees = Employee::with('departments')->paginate(50);
I want to filter this query result to be able to select only one chosen department and not all of them.
I tried adding to employee model this function
public function scopeDepartment($query, $department)
{
return $query->where('dept_no',$department);
}
but it isn't working. Can someone advice me how to filter query results with relations?

you can query within with relation as like
$employees = Employee::with(['departments' => function($q) use ($dept_id){
$q->where('dept_no',$dept_id);
}])->paginate(50);
$dept_id is the id of department i.e $dept_id = $request->department_id something like

Related

Laravel Eloquent relationship data retrieve

I have below code to get data from database,
$profile = Profiles::find(1);
$currency = Profiles::find($profile->currency_id)->currency;
Then created a relationship in the model as below,
class Profiles extends Model
{
use HasFactory;
protected $table = 'Profiles';
protected $primaryKey = 'profile_id';
public function Currency()
{
return $this->belongsTo(Currencies::class, 'currency_id');
}
}
class Currencies extends Model
{
use HasFactory;
protected $table = 'Currencies';
protected $primaryKey = 'currency_id';
public function profile()
{
return $this->hasOne(Profiles::class, 'currency_id');
}
}
Problem is that there is only 1 profile and 100 currency, currency_id is a foreign key in Profiles table,
I could not get data and get this error, Trying to get property 'currency' of non-object"
If i use $currency = Profiles::find(1)->currency; then it retrieve first row of Curriencies table which is not required data.
How can I get currency row for that specific profile?
The problem is that the find() method will look for the primaryKey and in your second call the currency_id is not the pk.
Two solution for you:
replace the find by a where clause like so: $currency = Profiles::where('currency_id',$profile->currency_id)->value('currency')
Or a more Laravel way to do it, through the relationship $currency = $profile->currency;

Laravel Eloquent for display row from subject table?

i have three database tables
category (id,name)
subcategory (id,name,category_id) foreign_key category_id on table category(id).
subject(id,name,subcategory_id) foreign_key subcategory_id on table subcategory (id).
i want a row containing the following -
subject_id subject_name category_name subcategory_id
how to do this using eloquent .and if approach is wrong .please suggest a good method to achieve the same .
Assuming you have the following models:
// Category Model
class Category extends \Eloquent {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
// Subcategory Model
class Subcategory extends \Eloquent {
protected $table = "subcategory";
public function category(){
$this->belongsTo('Category', 'category_id');
}
pubic function subject(){
$this->hasMany('Subject', 'subcategory_id');
}
}
// Subject model
class Subject extends \Eloquent {
protected $table = "subject";
public function subcategory(){
$this->belongsTo('Subcategory','subcategory_id');
}
}
You can get the data in your controller as follows:
// for subject with id 1
public function getOneRow(){
$subject = Subject::with('subcategory.category')->findOrFail(1);
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
return array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
// for all subjects
public function getOneRow(){
$subjects = Subject::with('subcategory.category')->all();
$out = array();
foreach($subjects as $subject){
// each row
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
$out[] = array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
return $out;
}
Edit for Laravel 5.1
Your models will be defined differently. Here's an example. Or follow the docs:
// Category Model Laravel 5.1
use Illuminate\Database\Eloquent\Model;
class Category extends Model {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
Edit: Completed the functions with return statements as requested in comment

Populate laravel object with relationships

I want to populate Every CustomerEvent with the Customer related to the CustomerEvent.
When I Loop through the object and call to $customerevent->customer foreach object I can get the customer related to that event but Can I populate the all objects in the main object without looping through every single event ?
I want to do something like this:
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
Here my code:
Table 1: "events"
id, customer_id
Model for Table 1 "CustomerEvent":
<?php
class CustomerEvent extends Eloquent{
protected $guarded = ['id'];
public $table = "event";
protected $softDelete = true;
public function scopeTypeOne($query)
{
$followUps = $query->where('type_id', '=', '1');
}
public function Customers()
{
return $this->belongsTo('Customer', 'customer_id');
}
}
Table 2: "customers"
id
Model for Table 2 "Customers":
<?php class Customer extends BaseModel{
protected $guarded = ['id'];
}
EventController:
public function index()
{
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
dd($customersWithTypeOne);
}
From you database scheme I see customer has many events, so I would recommend to define this relationship in you Customer model.
class Customer extends BaseModel{
protected $guarded = ['id'];
public function events()
{
return $this->hasMany('CustomerEvent', 'customer_id');
}
}
Then you will be able to query customers with events:
$customersWithTypeOne = Customer::whereHas('events', function($query){
$query->where('type_id', 1);
})->get()
Maybe Ardent can help you: https://github.com/laravelbook/ardent
It's an extension for Eloquent models and very popular.

Laravel 4 - How to use where conditions for relation's column

This is what I want, I have two tables. one is 'Restaurants' and other is 'Facilities'.
The tables are simple.. and One-To-One relations. like there is a restaurant table with id, name, slug, etc and another table called facilities with id, restaurant_id, wifi, parking, etc
Here are my models:
class Restaurant extends Eloquent {
protected $table = 'restaurants';
public function facilities() {
return $this->hasOne('Facilities');
}
}
class Facilities extends Eloquent {
protected $table = 'facilities';
public function restaurant() {
return $this->belongsTo('Restaurant');
}
}
I want do like this Select * from restaurants r left join facilities rf on r.id=rf.restaurant_id where r.name = 'bbq' and rf.wifi != '1'.
How to use Eloquent to do that?
ps. sorry for modify from https://stackoverflow.com/questions/14621943/laravel-how-to-use-where-conditions-for-relations-column#= , but I have the similar problem.
You can use where and other sql-based methods on the relationship objects.
That means you can either create a custom method in your model:
class Restaurant extends Eloquent {
protected $table = 'restaurants';
public function facilities($wifi) {
return $this->belongsTo('Facility')->where('wifi', '=', $wifi);
}
}
Or you can try to use query scopes:
class Restaurant extends Eloquent {
protected $table = 'restaurants';
public function facility() {
return $this->belongsTo('Restaurant');
}
public function scopeFiltered($query, $wifi)
{
return $query->where('wifi', '>', 100);
}
}
Then:
$wifi = 1;
$restaurants = Restaurant::facilities()->filtered($wifi)->get();
This isn't exactly what you need likely, but query scopes is likely what you want to use to get what you're attempting.
THe key point is to know that relationship classes can be used like query builders - for example:
$this->belongsTo('Facility')->where('wifi', '=', $wifi)->orderBy('whatever', 'asc')->get();
There are some ways to filter both, this is using QueryBuilder:
Restaurant::join('facilities','facilities.restaurant_id','=','restaurants.id')
->where('name','bbq')
->where('facilities.wifi','!=', 1)
->get();

Getting started with laravel (4) models

I'm trying out this model-thing, but I can't really get my grasp of it.
For the moment I have two tables (companies and sellers) "companies" as a column named "cResponsibleID" which I want to map to "sID" in "sellers".
models/Companies.php
class Companies extends Eloquent {
protected $table = 'companies';
protected $primaryKey = 'cID';
public function sellers() {
return $this->belongsTo('Sellers','sID');
}
}
models/Sellers.php
class Sellers extends Eloquent {
protected $table = 'sellers';
protected $primaryKey = 'sID';
public function companies() {
return $this->hasMany('Companies','cResponsibleID');
}
}
I then want to do something like Companies::with('sellers.sName')->get() to "translate" cResponsibleID to sName.
Maybe I'm all out wrong.
Thankful for all help.
Can you try printing the result of:
<?php
$company = Companies::with('sellers')->get();
echo '<pre>';
print_r($company->sellers);
And see how they're build up, I blieve the sellers.ANYTHING construction is only meant for multiple nested relations.
for example of a Seller has an Address as a relation, it would be Companies::with('sellers.address')

Resources