Query all where list id has user id - laravel

I'm trying to get all the properties, in a watchlist(s) where the list has a user id.
The relationship is set up as follows.
Each watchlist is related to a user id. Each Property has a watchlist id.
I need all properties, in all the watchlists belonging to that user.
The watchlist gets the user_id automatically upon creation.
Here are my models
Watchlist
public function properties(){
return $this->hasMany('App\WatchedProperties');
}
public function user(){
return $this->belongsTo('App\User');
}
WatchedProperties
public function watchlist(){
return $this->belongsTo('App\Watchlist');
}
Query
Gets all books in every list disregarding user ids and list ids
$Watchlists = WatchedBooks::all();
Currently gets all books regardless of userid.
I need all books in all of the user's lists.
A user could have multiple lists
List A
List B
So something like
All books from all lists where the list id is related to user id.
This is what the Watchlist DB looks like
WatchlistDB
This is what the WatchedBooks DB looks like
Books in watchlist

Laravel has a beautiful solution for this: you can add a ->hasManyThrough relation to the user model. You can find more information about this type of relation in the Laravel documentation about Eloquent relationships.
The user model will look like this:
class User extends Model {
[...]
public function watchedBooks()
return $this->hasManyThrough('App\WatchedBook', 'App\Watchlist');
}
[...]
}
Then you can get all the WatchedBooks, associated with the user, using
$user->watchedBooks;
or
$user->watchedBooks()->yourBuilderQueryHere()->get();

whereHas allows you to query in relationships. More information on this can be found at https://laravel.com/docs/5.6/eloquent-relationships#querying-relationship-existence
$Watchlists = WatchedBooks::whereHas('watchlist', function($query) use ($user_id){
$query->where('user_id', $user_id)
})->get();
The script above gets all WatchedBooks that are associated with a Watchlist that is owned by a user ($user_id).

Related

Invalid argument supplied for foreach() in laravel when use Eloquent: Relationships

I wanna get the class name of a user via the user ID. When I input the ID of a user so I will wanna get the class name. I have three tables such as users table, classes table, and class_users table. The class_users table is born from two users table and classes table.
A users table has an id, name, email, password.
A classes table has an id, class_code, class_name.
A class_users table has an id, class_id, user_id
And this problem relates to Eloquent Relationships.
Thank you for help.
My Route:
Route::get('/find_classes/{id}','StudentController#find_classes');
My Controller function:
public function find_classes($id)
{
$users = User::find($id);
foreach($users->classes as $class)
{
echo $class->name . '<br';
dd($class);
}
}
My User Model:
public function classes()
{
return $this->belongsTo('App\Classes','class_users','user_id','class_id');
}
Looks like you might have the wrong relationship set up on your User model. You have a one to many set up, but your DB is setup to handle a many to many. I suggest you change your User model relationship:
public function classes()
{
return $this->belongsToMany('App\Classes');
}
Note, you may need to name the FK on that relation, as I see you have class_id on the table, but your actual class is named 'Classes'. Check through your relationships to ensure this is explicit on the FK where it doesn't follow Laravel convention exactly.
With this relationship, your foreach loop should work. It would be a good idea for efficiency, as mare96 noted, to eager load the classes on the $users collection when you query:
$users = User::with('classes')->find($id);

Laravel: return multiple relationships

I have the following table:
The table is called user_eggs and it stores the user eggs.
eggs are items with additional data (hatch_time)
As you can see, user 2 has 2 eggs, which are items 46 and 47.
My items table stores the item general information such as name, image, description, etc...
How I can return the user eggs using $user->eggs() including the item data in my items table of the egg item_id?
I tried:
User Model:
/**
* Get the eggs
*/
public function eggs()
{
return $this->belongsToMany(Egg::Class, 'user_eggs','user_id','item_id')
->withPivot('id','hatch_time');
}
but $user->eggs() returns an empty array.
Any ideas?
A simple approach will be:
in your UserEgg model define:
/**
* Get the user associated with egg.
*/
public function _user()
{
return $this->belongsTo('App\User','user_id');
}
/**
* Get the item associated with egg.
*/
public function item()
{
return $this->belongsTo('App\Item','item_id');
}
then in your controller:
use the model to extract everything like this:
$userEggs = UserEgg::where('user_id',2)->get();
foreach($userEggs as $userEgg){
$associateduser = $userEgg->_user;
$associatedItem = $userEgg->item;
}
Short answer
If you loop through the user's eggs:
foreach($user->eggs as $egg){
$item = Item::find($egg->pivot->item_id);
}
If you want to query:
$user->eggs()->wherePivot('item_id', 1)->get();
Long answer
From the Laravel Documentation
Retrieving Intermediate Table Columns
As you have already learned, working with many-to-many relations requires the presence of an intermediate table. Eloquent provides some very helpful ways of interacting with this table. For example, let's assume our User object has many Role objects that it is related to. After accessing this relationship, we may access the intermediate table using the pivot attribute on the models:
$user = App\User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->created_at;
}
Notice that each Role model we retrieve is automatically assigned a pivot attribute. This attribute contains a model representing the intermediate table, and may be used like any other Eloquent model.
By default, only the model keys will be present on the pivot object. If your pivot table contains extra attributes, you must specify them when defining the relationship:
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
If you want your pivot table to have automatically maintained created_at and updated_at timestamps, use the withTimestamps method on the relationship definition:
return $this->belongsToMany('App\Role')->withTimestamps();
Filtering Relationships Via Intermediate Table Columns
You can also filter the results returned by belongsToMany using the wherePivot and wherePivotIn methods when defining the relationship:
return $this->belongsToMany('App\Role')->wherePivot('approved', 1);
return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);

laravel one-to-many get data without inner join

I am trying to get a feel around the laravel ORM and I have the following models.
I have a:
user table with- id, firstname, lastname
city table with - id, name
usercity table with - user_id, city_id
The usercity table tracks the cities the user has visited.
I added the following in city model:
public function usercity()
{
return $this->hasMany('App\UserCity');
}
And another function in user model
public function usercity()
{
return $this->hasMany('App\UserCity');
}
I also added a model for UserCity and added following function there.
public function city()
{
return $this->belongsTo('App\City');
}
public function user()
{
return $this->belongsTo('App\User');
}
Now, the goal is to retrieve all the cities a user has visited. I used the following function.
$usercities = User::where('id','=',1)->first()->usercity()->get();
This works in the sense that it retrieves the user_id and city_id.
What would i need to do to get all the fields in the city table also?
Current response:
[[{"user_id":"1","city_id":"1"},{"user_id":"1","city_id":"2"},{"user_id":"1","city_id":"3"},{"user_id":"1","city_id":"4"}]]
I might be able to use inner join but I wanted to see if there was another way to retrieve the data which safely populates the data for me.
What you really have is a many-to-many relationship between users and cities, with the usercity table being the pivot table. Laravel uses the BelongsToMany relationship to implement this. You'll need to make a few changes to get this to work.
In your city model:
public function users() {
return $this->belongsToMany('App\User', 'usercity');
}
In your user model:
public function cities() {
return $this->belongsToMany('App\City', 'usercity');
}
You can get rid of the UserCity model. There is usually no reason to need a model for the pivot table.
The usercity table may need to be updated to add an id field as the primary key. I've not tried it without one, however, so it may work as you have it. Also, if you wanted, you could rename the table to city_user to conform to Laravel conventions, and then you wouldn't need to specify the table name in the relationship definitions.
Once your relationships are setup correctly, you can access a user's cities via the cities relationship on the user, and you can access a city's users via the users relationship on the city. For example:
// all of the cities visited by user 1
$user = User::find(1);
$usercities = $user->cities;
// all of the users that have visited city 1
$city = City::find(1);
$cityusers = $city->users;
You can find more information about the relationships in the documentation here.

How to get all related items like "with" in Laravel?

I'm sorry, I don't even know how to ask for what I need...
User:
id
MyItem:
id
item_id
user_id
Item:
id
How to get $user->items()?
I guess hasManyThrough() won't help here.
Thank your very much for help.
If you have defined your relationship and have items relation in your User model, you can get them using:
foreach ($user->items as $item) {
echo $item->id;
}
As it's many to many relationship, in class User you need to define your relationship this way:
public function items() {
return $this->belongsToMany('Item');
}
and in Item class this way:
public function users() {
return $this->belongsToMany('User');
}
And your pivot_table should have here name item_user. If it's not, pass your table name as 2nd argument to belongsToMany method
I don't know what you want exactly but
i think you need user relative more information
if you want user relative in formation
so please try this
you get all information about user
$users = User::all();

Laravel Counting and retrieving many to many relationships

I have a many to many Laravel Relationship Many Users have Many Roles
I know that I can do User::find(1)->roles()->get() to get all roles with an ID of 1 for a User but this requires me to know the ID of the role as oppossed to just its names
What sort of eloquent query could I put in my user Repository to do something like
public function getAllUsersWithRole($roleType){
//Query goes here
}
Where $roleType is the name of the Role. So I need to look up the ID of the role based on hte name and then return users that have that role ID in the pivot table
does this look like what you want:
public function getAllUsersWithRole($roleType){
$role= Role::where('name', $roleType)->first();
$users= $role->users;
return $users;
}
If you have correct relation definitions in your Eloquent models you should be able to get the users by the role name this way:
$roleType = 'YourRoleName';
$users = Role::whereType($roleType)->first()->users;
Grab the users, then get the roles for all the users.
public function getAllUsersWithRole($roleType){
$users = User::where('role_type', '=', $roleType)->get();
$roles = $users->roles()->get();
return $roles;
}

Resources