Eloquent nested relationship - mysql

i have a question to my db query.
My DB tables/schema:
customers_users (customer_id, user_id) relationship table
projects (project_id, customer_id, [.......]) belongs to customers
i try to get all Projects where a user has access through customers to, with the following query:
//call
User::find(Auth::id())->first()->projects();
//User.model
public function projects() {
return User::with('customers.projects')->get();
}
It works. But now i have User data, Customer data and Project Data in the result array. I want only the Projects. Is there an other way?

$user = auth()->user()->load('customers.projects');
$projects = $user->customers->pluck('projects')->collapse()->unique();

Related

Filter Table, based on field in another table

I'm stumped with this. I have a table with various fields:
$employees. This, I guess, is what you call a collection, I think, that when I call, returns all employee records in the database (4 records in this example)
Each employee record has the following fields
first_name, last_name, age, other_id
There is another table (or collection), which I'm calling filter table. It is called $other_ids. This has two records, with the following fields - id, id_name.
I want to be able to filter the $employees table so that it only keeps the records, where other_id is equal to one of the two values of id in the filter table- $other_ids
So for example, if the filter table has the following two records:
[{"id":1 "id_name":"one"}, {"id":2, "id_name":"two"}]
And the $employee table contains the records:
[{"first_name":"ted", "surname_name":"stark", "age":35, "other_id":1},
{"first_name":"fred", "surname_name":"strange", "age":30, "other_id":2},
{"first_name":"incredible", "surname_name":"hulk", "age":25, "other_id":3},
{"first_name":"captain", "surname_name":"stone", "age":28, "other_id":2}]
After, the filtering, it should return $employees_filtered should only have records 1, 2, and 4
I've tried doing left-join and using whereHas, and where clauses, but nothing works!
I think you are looking for something like -
$otherId = [1, 2];
$employees_filtered = Employee::with('Others')->whereIn('other_id', $otherId)->get();
Please don't forget to make a relationship with their model.
In Other.php model -
public function Employees()
{
return $this->hasMany('App\Other', 'other_id', 'id');
}
And in Employee.php model -
public function Others()
{
return $this->belongsTo('App\Employee', 'other_id', 'id');
}

fetching data from three tables in laravel

The is the table structure,which basically has three tables,namely expenses,categories and sunbcategories
table expenses
(id,category_id,sub_category_id,date,description,amount)
table categories
(id,category_name)
table subcategories
(id,sub_category_name,category_id)
This is the SQL query that is needed
select expense.date, expense.description, expense.amount,
category.category_name, subcategory.sub_category_name
from expenses as expense,categories as category,subcategories as subcategory
where expense.category_id=category.id and
category.id=subcategory.category_id);
This is the function in Expense model with which I pass the category_id
The same query mentioned above is written in laravel, but I am not able to
fetch the data.
function fetchExpenseData($categoryId)
{
$expense = Expense::select("expenses.*","categories.category_name as
Categoryname","subcategories.Sub_category_name")
->join("categories","categories.id","=","expenses.category_id");
->join("subcategories",function($join)
{
$join>on("subcategories.category_id","=","expenses.category_id")
->on("suncategories.id","=","expenses.sub_category_id")
})->get();
return $expenses;
}
$expenses that are returned will be printed in blade.php.
Can I know what is the mistake
thanks in advance
Hye there ,
You need to add eloquent model for retrieving data fromenter code here three tables
Like
I have School Table , Student Table , Teacher Table
School is relating with both Student and Teacher then we will add relationship
In School Model
`
public function getStudent(){
return $this->hasMany('student_id' , App\Student);
}
public function getTeachers(){
return $this->hasMany('teacher_id' , App\Teacher);
}
In Student table
public function getSchool(){
return $this->hasOne('school_id' , App\School);
}
`
now call data from student
`
$students = Student::with('getSchool.getTeachers')->get()
This Demonstration for what I have get from your Question

NodeJS: Nested SQL query for custom REST API endpoint

I am creating a REST-API via NodeJS at the moment.
I created a MySQL database with these two tables:
table: physiotherapist = {(physio_id),(surname),(lastname),(appuser_id)}
--> PK = (physio_id)
--> FK = (appuser_id) and points on the PK of the second table
table: app_user = {(user_id),(username),(password)}
--> PK = (user_id)
For the REST-API endpoint I need the data of both tables.
For example, when I want the information of user with the id=3 and the api-enpoint is like 'localhost:3306/appusers/3' I want the data of both tables as a result.
This is what I got at the moment:
getUserById:function(id, callback) {
return db.query("Select * from user_physiO_app where user_id=?", [id], callback);
it'S only the data from the first table, so how do I get the data of the second table?
Thanks in regard!
Solved after the friendly advice of #Evert: I used the INNER JOIN syntax.
getUserById:function(id, callback) {
return db.query("Select * from user_physiO_app inner join physiotherapeut on
user_physiO_app.user_id = physiotherapeut.physiO_user_id where user_id=?", [id], callback);
}

How to fetch records from two different tables in laravel5.2

I have two tables 'approval' and 'renewal', both having a common column 'applicant_id'.
When new application comes-in, it stores a data-record in table 'approval' alongwith the 'applicant_id' for whom the record has been added.
Now, when there is a renew applied for that same applicant, the row gets created in the table 'renewal' referencing the 'applicant_id'
Note: There can be a single record in the table 'approval' for a 'applicant_id' but there can be more than one record for the same 'applicant_id' in the table 'renewal'.
Now, my requirement is:
I need to fetch the records from both the table for all the applicants.
Conditions: If there is a data for the 'applicant_id' in both the table and 'renewal' table has multiple row for the same 'applicant_id', then I need to get the records from 'renewal' table only that too the latest one.
If there is no data in 'renewal' table but exists in 'approval' table for the 'applicant_id', then the fetch record should get the data present in 'approval' table.
Basically, if there is record for the applicant in 'renewal' table, get the latest one from there, if there is record present only in 'approval' table, then get that one but the preference should be to get from 'renewal' if exists.
I am trying to do this in laravel 5.2. So, is there anyone who can help me in this?
If you're using Eloquent, you'll have 2 models:
Renewal.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Renewal extends Model
{
protected $table = 'renewal';
public static function findMostRecentByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->orderBy('date_created', 'desc')
->first();
return $applicant;
}
}
Approval.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Approval extends Model
{
protected $table = 'approval';
public static function findByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->first();
return $applicant;
}
}
Then, in the code where you want to get the approval/renewal record, use the following code:
if (! $record = Renewal::findMostRecentByApplicantId($applicantId)) {
$record = Approval::findByApplicantId($applicantId);
}
//$record will now either contain a valid record (approval or renewal)
//or will be NULL if no record exists for the specified $applicantId
After few try, I got one way to do it using raw:
SELECT applicant_id, applicant_name, applicant_email, applicant_phone, renewed, updated_at
FROM (
SELECT renewal_informations.applicant_id, renewal_informations.applicant_name, renewal_informations.applicant_email, renewal_informations.applicant_phone, renewal_informations.renewed, renewal_informations.updated_at
FROM renewal_informations
UNION ALL
SELECT approval_informations.applicant_id, approval_informations.applicant_name, approval_informations.applicant_email, approval_informations.applicant_phone, approval_informations.renewed, approval_informations.updated_at
FROM approval_informations
) result
GROUP BY applicant_id
ORDER BY applicant_id ASC, updated_at DESC;
For every single Approval id, there can b multiple records for renewal table suggests you have One to Many relation. which you can define in the your Model like
Approval.php (App\Models\Approval)
public function renewal()
{
return $this->hasMany('App\Models\Renewal', 'applicant_id')
}
Having defined this relation. you can get the records from the table using applicant_id.
$renewal_request_records = Approval::find($applicant_id)->renewal();
This will get all records from renewal table against that applicant_id.
Finding the latest
$latest = Renewal::orderBy('desc', 'renewal_id')->first();
Further Readings Eloquent Relations

Building an entity join LINQ query

I have the following table strutucture and am accessing them by using MySQL Entity Framework:
Table Users
- Id
- Name
Table Subscriptions
- Id
- Id_User
- Id_Course
Table Courses
- Id
- Name
What I would like and am having a hard time to do so is building a link query for all users that returns a list with each entry containing:
User Id;
User name;
Concat string separated by comma with all courses for the user or 'no courses' string if none.
This list should be filtered by a part of users name.
I've started to build the code but can't finish it:
var Model db = new Model();
var list = from user in db.Users
join ???
where user.Name.Contains(filter.Trim())
select new { Name = user.Name, Id = user.Id, ???}
Can anyone help me please ?
You should use navigation properties (like User.Subscriptions) for this. Depending on how you created the model they may already be there, else you first should add them.
var query = from u in db.Users
where user.Name.Contains(filter) // trim the filter value first
select new
{
u.Name,
u.Id,
Courses = u.Subscriptions.Select(s => s.Course.Name)
};
var result = query.AsEnumerable()
.Select(q => new
{
q.Name,
q.Id
Courses = string.Join(", ", q.Courses)
};
The reason for doing this in two phases is that string.Join can't directly be used in an EF LINQ expression (can't be turned into SQL) so it must be done in memory (i.e. after an AsEnumerable).
But still it may be efficient to do a projection first (the first part), otherwise too much data may be fetched from the database.