Get result from laravel relation - laravel

I am using laravel VERSION = '5.6.22' . I have two tables t_project_employee and employees table
In t_project_employee i am storing the project_id and assigned employees.
eg pe_emp_id emp_id
01 25
01 36
02 25
In employee table i am storing employee details.
I am trying to fetch all employees who is assigned for a particular project.
public function employees(){
return $this->hasOne('App\Employee','emp_id','pe_emp_id')->select(array('emp_id', 'f_name','l_name'));
}
I am getting all projects and inside project i am getting employees. i need only employees details assigned to the projects. i done using the above code. how can i do this
return TProjectEmployees::where("pe_prj_id",$projectId)->with("employees")->get();
I am using above code in controller
[
{
"pe_id": 1,
"pe_prj_id": 1,
"pe_emp_id": 54,
"pe_role_id": 1,
"pe_startdate": "2018-07-11",
"pe_enddate": "2018-07-19",
"pe_IsActive": 1,
"employees": {
"emp_id": 54,
"f_name": "Aglubat Micheal",
"l_name": "Nicolas"
}
},
is the result. I dont need the project details, I only need the employees

As i show above example you have used hasOne relation as per my opinion use belongsTo relation because one project may be assign to multiple employee right? so your code will become like below:
public function employees() {
return $this->belongsTo('App\Employee','emp_id','pe_emp_id')->select(array('emp_id', 'f_name','l_name'));
}

You have a faulty relationship here. t_project_employees seems like an intermediate, or pivot, table for a many-to-many relationship. Therefore, you wouldn't have a model for that table or ever query that table directly. You'd have a belongsToMany relationship on both the Projects and Employees Model.
Employee Model:
public function projects()
{
return $this->belongsToMany(Project::class, 't_project_employees');
}
Then query that relation: https://laravel.com/docs/5.6/eloquent-relationships#querying-relations.
Employee::whereHas('projects', function($q) use ($projectId) {
$q->where('id', $projectId);
});

Related

Laravel: show data in laravel with two table

I want to display data in laravel.
This is the classrooms table:
This is the students table:
this is the classroom_student table :
I expect a result like this:
With class from the classroom table, year from the student table (the year the student was created), and data from the student table (data for each month, sample data:[2,4,6] means Jan: 2, Feb: 4, Mar: 6). I don't know how to make it. Can you help me? thank you
You need to setup a many to many relationship both of your models (classroom model and student model. It will look something like this:
class Classroom extends Model {
public function students(){
return $this->hasMany(Student:class, 'student_id');
}
}
class Student extends Model {
public function classrooms(){
return $this->hasMany(Classroom:class, 'classroom_id');
}
}
Here is also a reference to laravel docs for the exact solution:
https://laravel.com/docs/8.x/eloquent-relationships#many-to-many
You Should use HasMany Relation in both Models and while fetching data call this relation function to get data related to other model and set expected title for those data in Transformer.

Getting the result of a trailing pivot table

Basically, I have three tables which are users, position, user_position and I want to get all users with their respective positions
Note that a single user can have multiple positions
The `user_position` table consists of:
- user_id
- position_id
To illustrate... it goes something like this:
users-->user_position<--position
What I got so far is this:
User Model
public function user_positions() {
return $this->hasMany('App\Models\UserPosition', 'user_id', 'id');
}
UserPosition Model
public function positions() {
return $this->hasMany('App\Models\Position', 'position_id', 'id');
}
UserController
public function getallusers() {
$data = User::with('user_positions')->get();
return response()->json($data);
}
So far it gives me the correct result set.
For example:
[{id:1,
name:'John',
user_positions:
[{id:1,
user_id:1,
position_id: 5
},
{id:2,
user_id:1,
position_id: 9
}
]
}]
However, it is incomplete, I also wanted the positions array inside the user_positions array but I don't know or I got lost on how to associate/merge/attach (i dont know the right term) the positions function to my User Model.
What you are looking for is a BelongsToMany relation.
You could add the following relation to your User model.
public function positions()
{
return $this->belongsToMany(Position::class);
}
You could eager load them with:
User::with('positions')->get();
Result:
[{
...
"positions": [{ ...The data of the position... }]
}]
When you want to m:m relation, it's advised to use BelongsToMany, there is no need for an intermediate model for the "pivoted" table.
If you have non-eloquent standard naming conventions. Then you have to specify the table name in the 2nd parameter as followed:
return $this->belongsToMany('App\Models\Positions', 'tbl_positions_assigned');
In the 3rd and 4th parameter you specify the foreign key names.
I'd like to refer to you to the documentation Eloquent-relationships as it's very thoroughly explained over there.
One very strong thing you can do with belongsToMany is to append extra columns in the pivot table. Those are also easily obtained from the pivot table. This is useful if you wish to store extra data values specific to the model.
return $this->belongsToMany('App\Models\Positions')->wherePivot('active', 1);
With above example you could exclude certain values, that are not active in this example, when you retrieve the results from the query.

Laravel whereHas ManyToMany relation but then order by a value in the third table

I have 3 tables
entry (
id,
title,
other_stuff)
entry_award (
id,
award_id,
entry_id)
award (
id,
name,
type)
I am trying to create a laravel query which lets me get all the entries that have awards, and order them by award.type ASC
$Entries = Entry::with('award')
->whereHas('award', function ($query) {
$query->orderBy('award.award_id','ASC');
})->paginate(20);
But this doesn't work.
This is the sql version of it
SELECT DISTINCT entry.*
FROM entry, award, entry_award
WHERE entry.id = entry_award.entry_id
AND award.id = entry_award.award_id
ORDER BY award.type ASC;
Now I tried to just use the raw sql for it, but the problem seems to be that laravel does not then recognize the result as Entry models/objects. And i need to get other Entry relations later on in the html via blade.
So how can I either make a query-builder query that gets me all entries that have awards and orders them by award.type value
or use the raw sql but have Laravel see it as an array of Entry
objects instead of just an array of JSON values.
class Entry extends Model {
public function entry_award(){
return $this->belongsToMany('App\Award', 'entry_award');
}
}
class Award extends Model {
public function entries() {
return $this->belongsToMany('App\Entry', 'entry_award');
}
}

Selecting specific column in ORM relationship Laravel 5.5

I have an order table with a primary key id and another table trips. I trip can have many orders. I have defined the relationship in this way
public function orders_currency() {
return $this->hasMany('App\Order', 'trip_id', 'id')->select('id', 'converted_currency_code');
}
Although I know that, I have to select id of the order table in order to get the result, that's why I am mentioning to select the id of the order table.
Despite this, I am getting the orders_currency index empty. Which angle am I missing in this case?
Any clue will be appreciated.
Did you set up the model correctly?
You'd do something like this in your model script I suppose
class Trips extends Model
{
public function orders() {
return $this->hasMany('Order');
}
I got the solution by doing this way
public function orders_currency() {
return $this->hasOne('App\Order', 'trip_id', 'id')
->select('trip_id','converted_currency_code');
}
I had to select referencing key in this case.

Laravel 5.5 - whereIn and whereNotIn in same eloquent query?

I have two tables where I need to pluck the valid building ids (those that match the $buildingIds array) that exist in buildings AND must ensure they don't already exist in buildings_built (so we know which buildings need to be built). It can be done in two queries easily, but I am trying to do it with a single query to be more efficient:
$buildingIds = ['a1','b2','c3'];
Tables
// buildings (id, building_name) (a1, adam) (b2, barney) (c3, castor)
// buildings_built (id, building_id) (1, a1) (2, b2)
Here is my attempt at this that doesn't work properly:
$buildingsToBuildFromIdsArray = Buildings::whereIn('buildings.id', $ids)
->whereNotIn('buildings_built.building_id', $ids)
->pluck('buildings.id');
Ideally, the query should return ['c3'], since that building exists in buildings table and does not exist in buildings_built table (has not been built yet).
Any idea how to get it to work correctly?
What you could do is to create a relationship between two models - I will work with the default naming for models as Building and Build:
class Building extends Model
{
public function builds(): HasMany
{
return $this->hasMany(Build::class, 'building_id', 'id');
}
}
class Build extends Model
{
public function building(): BelongsTo
{
return $this->belongsTo(Building::class, 'id', 'building_id');
}
}
To fetch your records you could then use the doesntHave query builter method
Building::whereIn('id', $ids)->doesntHave('builds')->pluck('id');

Resources