laravel elequent way to find single row from table - php

hello I am new to laravel and maybe I am a bit confused between eloquent and query builder way for writing a query but anyway can you please tell me what could be the best eloquent way to retrieve info like this in laravel 6 or 7
User > hasMany > Recipes
Recipe > belongsTo > User
I want to check if user id 2 present in users table then get only one post which id is 3

Query builder is for explicitly building SQL queries, and does not return instances of your models. Eloquent query builder, is similar but the result will contain the model(s) loaded with all their attributes, and has some handy functions for querying the relations you define in your models.
Given the limited information in your post, I am assuming when you say a post, you mean a recipe:
Query Builder:
DB::table('users')
->join('recipes', 'recipes.user_id', '=', 'users.id')
->select(['users.some_col', ... 'recipes.some_col'])
->where('users.id', 2)
->get();
If you have your models setup with the relations. You can use Eloquent like so:
User::where('id', 2)->with('recipes')->get();

If I understand you correctly it would be like this:
User::whereId($userId) //asuming it is 2
->with(['recipes' => function($q) use($recipeId) {
$q->where('id', $recipeId); //assuming it is 3
}])->first();

you can do this if i understand correctly:
$user = User::findOrFail(2); //auto 404 if user not found
$recipe = $user->Recipes()->where('id',3)->first();

You may use conditional eager loading for better performance.
$userId = 2;
$receiptId = 3;
$user = User::with(['receipts'=> function ($query) use($receiptId){
$query->where('id', $receiptId);
}
])->find($userId)

Related

Laravel: Orderby in related table and with

This is my model
User
Role
and relationship between of those models are many to many.
I want to create query like this:
return User::with('roles')->orderBy('roles.id')->paginate();
I don't want join because I created a base class for every model. I also don't want use orderBy after get because it must load all of my data and after that I should be able to sort and paginate it. So it is not a very good idea.
You can try something like this:
return User::with(['roles' => function ($query) {
$query->orderBy('id', 'desc');
}])->paginate();
But this will only order the eager loading attributes, but if you are interested to use join you can have something like this:
return User::with('roles')
->join('roles', 'user.id', '=', 'roles.user_id')
->orderBy('roles.id', 'desc')
->paginate();
In this you can easily use paginate which is your main concern.
Hope this helps.
User::where('role_id','!=','0')->orderBy('role_id','DESC')->paginate(10);

multiple "has many through" with eloquent of laravel

I came accros a problem with laravel's ORM, eloquent and found no solution yet.
I have some tables as follows
Team
- id
- name
User
- id
- name
- role
- team_id
Student_Info
- id
- user_id
- data1
- data2
- etc ...
Project
- id
- student_id
- name
Now, I want to query all projects a certain team, where team = 'some team'
Now the thing here is, without an ORM, it's simple, I would have done multiple joins in raw SQL.
However, because all these tables have a common column "name" I will have to alias all this stuff, which is really boring
With eloquent I can't find a way to do this query using "has many through" because it only allows on intermediate and I can't do a raw SQL as the alis thing is really a pain in the ass and as it would be very difficult to map the result to laravel's Models
There is no native relationship for this case.
I created a HasManyThrough relationship with unlimited levels: Repository on GitHub
After the installation, you can use it like this:
class Team extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function projects() {
return $this->hasManyDeep(Project::class, [User::class, StudentInfo::class],
[null, null, 'student_id']);
}
}
$projects = Team::where('name', 'some team')->first()->projects;
Try with relationship existence. This assumes you have all relationships properly defined
$projects = Project::whereHas('students.user.team', function ($query) {
$query->where('name', '=', 'some team');
})->get();
That's 3 levels of nesting. Never tested. However, if you already define a Project-User relationship via hasManyThrough() you can shorten it to 2 levels only.
$projects = Project::whereHas('user.team', function ($query) {
$query->where('name', '=', 'some team');
})->get();
Those will give you the data for projects only. If you also want the the intermediate data, use eager loading instead with with(). Just replace whereHas() by with().
$projects = Project::with('user.team', function ($query) {
$query->where('name', '=', 'some team');
})->get();

Laravel RelationShip (join with where)

I need help with Laravel 5 (using Eloquent)
I have 2 tables...
Model Driver
drivers
id
company
Model DriverOnline
drivers_online
id
name
driver_id
I need to search for a result on (company=1 and driver_id=driver.id).
Please help me!
If you want to only fetch Driver based on a condition, you can just do this:
Driver::with('online')->where('company', 1)->get();
If the clause is on the relationship, use with and specify a query on that.
$company = 1;
$drivers = Driver::with(['online' => function($query) use ($company)
{
$query->where('company', $company);
}]);
See "Eager Load Constraints":
https://laravel.com/docs/5.0/eloquent
Take note of my use. This allows you to include variables from the scope into your Closure instance.
And be aware, if you use either solution, you must set up a relationship. Consult the link I shared with more information on that.
Edit: As per our conversation.
$drivers = Driver::where('company_id','=',1)
->with('driversOnline')
->whereHas('driversOnline', function($query) {
$query->where('online','=',1);
})
->get();

Laravel4, eager loading is not working

I'm trying to get "reviews" from my database where the user is from MX (for example) so, I have this:
Review::with(array('user' => function($query)
{
$query->where('country_code', '=', 'MX');
}))
->with('user.country','pictures')
->where('shop_id',Input::get('id'))
->orderBy('id','DESC'))
->get()
->toArray()
But seems to be like where('country_code', '=', 'MX') is not taken into account because retrieve all reviews and I just want the reviews written by the user from MX.
user and picture inside with are functions within my User model
country_code is a field from users table
The goal is: Just get the reviews written by a user from the country specified, and was testing something like this:
Review::where('shop_id',Input::get('id'))
->with('user.country','pictures')
->where('users.country_code','MX')
->orderBy('id','DESC'))
->get()
->toArray()
But is not working as well because says: Unknow column users.country_code in where....
You want to do a query that filters based on the relation. Eager loading constraints only constrain the records that come with your main result set.
Review::whereHas('users', function ($q)
{
$q->where('country_code', 'MX');
})
->with('user','pictures')
->where('shop_id',Input::get('id'))
->orderBy('id','DESC'))
->get();
The whereHas is saying ... give me only Reviews that have a User with country_code=MX.
Reference
Laravel Docs - Eloquent - Querying Relations
If you want reviews written by a certain user or group of users you don't want to use eager loading. Try this:
Review::with(array('user', 'pictures'))
->join('users', 'reviews.user_id', '=', 'users.id)
->where('users.country_code', '=', 'MX')
->where('reviews.shop_id', Input::get('id'))
->orderBy('reviews.id', 'DESC'))
->get();

Querying on related models using Laravel 4 and Eloquent

Using Laravel 4 I have the following models and relations: Event which hasMany Record which hasMany Item. What I would like to do is something like this
Item::where('events.event_type_id', 2)->paginate(50);
This of cause doesn't work as Eloquent doesn't JOIN the models together when retrieving the records. So how do I go about this without just writing the SQL myself (which I would like to avoid as I want to use pagination).
What you want is eager loading.
It works like this if you want to specify additional constraints:
Item::with(array('events' => function($query) {
return $query->where('event_type_id', 2);
}))->paginate(50);
There is a pull request pending here https://github.com/laravel/framework/pull/1951.
This will allow you to use a constraint on the has() method, something like this:
$results = Foo::has(array('bars' => function($query)
{
$query->where('title', 'LIKE', '%baz%');
}))
->with('bars')
->get();
The idea being you only return Foos that have related Bars that contain the string 'baz' in its title column.
It's also discussed here: https://github.com/laravel/framework/issues/1166. Hopefully it will be merged in soon. Works fine for me when I update my local copy of the Builder class with the updated code in the pull request.

Categories