Eloquent query not working - php

I have a many to many relationship between users and categories. In a third table, I have a field called category_id to reference what category each record belongs to. I am setting up a system where by once a user logs in, I want them to see records that has category_id of the categories they've selected when registering.
My code is shown below
I have this relationship setup in users model,
public function categories()
{
return $this->belongsToMany('App\Category');
}
and also this
public function userCats()
{
return $this->categories()->get();
}
in the categories table i have this relationship setup
public function users()
{
return $this->belongsToMany('App\User');
}
in my 3rd Table controller i have the following code
if(Auth::check()){
$servo = Jumong::postOnly()->whereIn('category_id', Auth::user()->userCats())->get();
} else {
$servo = Jumong::all()->where('type','P');
}
dd($servo);
The problem is that the below part,
Auth::user()->userCats()
It returns only the last 2 records in Jumong table and there are more than that.
If I replace it with an array, it will return the right results.
Any ideas on what I am missing?

It doesn't work because whereIn expects an array of ids whereas
Auth::user()->userCats() returns a collection of categories.
You can still doing something like.
Auth::user()->categories->pluck('id')

Related

1 to 1 and 0 to many relationship Laravel not working

I am struggling with an eloquent request. Let me explain what I want to do:
I have two models: User and Item
One User can have many Item and one Item belongs to One user.
I wrote the two method for this relation in my models as followed:
class Item extends Model
{
public function user() {
return $this->belongsTo(User::class);
}
}
class User extends Model {
public function items() {
return $this->hasMany(Item::class, 'items', 'user_id', 'user_people_id');
}
}
I try to access to the items from my controller its user's relation with:
public function index()
{
$items = Item::with('user')->get();
dd($items);
FYI: I seeded my items table with 10 items and my user table with 4 users:
items table:
users table:
My problem is that in the when I check my query with dd() here is what I get: Only the 4 first items get the relation, the others 6 return a null value
Relation working:
Relation returning null:
Thank you for helping me!
According to Laravel doc, hasMany relationship parameters are the following:
return $this->hasMany(Myclass::class, 'foreign_key', 'local_key');
So try to change your relationship in your User class like that
// change this
return $this->hasMany(Item::class, 'items', 'user_id', 'user_people_id');
// to this
return $this->hasMany(Item::class, 'user_people_id', 'id');
The easiest solution would be to rename your foreign key to user_id. That is what Laravel expects, so you won't need to deal with extra arguments in your hasMany() functions.
If you can't do that I think this'll work: return $this->hasMany(Item::class, 'user_people_id');.
Please try to add all in your query to see if it will work:
Update
public function index()
{
$items = Item::all();
dd($items);
}

Make Laravel Accessor return query results

UPDATED:
I'm trying to add my own attribute with subquery results to the results of main query.
Now, I have Many-To-Many relation between three tables: Tournaments, Participants and Users.
Here is the defining of relation in Tournaments model:
public function users() {
return $this->belongsToMany('App\User', 'Participants', 'Id_tourn', 'Id_user')->withPivot('Rating');
}
The structure of tables is:
Users:
-Id
-Name
Participants:
-Id
-Id_user
-Id_tournament
-Final
-Final_place
Tournaments:
-Id
-Name
I need to have extra Winners attribute in my final query result where I'll have info of first three places.
Following the documentation, I've created an accessor and tried different variants:
That just freeze the system. Nothing happenes and in 30 second I get timeout error.
public function getWinnersAttribute() {
return Tournaments::where("Id","=",$this->attributes['Id'])->where("Finals","=",1)->limit(3)->orderBy("Final_place","asc")->get();
}
This returns an error that "finals" column is not fount in Tournaments table, so $this doesn't have relation:
public function getWinnersAttribute()
{
return $this->where("Finals","=",1)->limit(3)->orderBy("final_place","asc")->get();
}
This returns blank white page without anything:
public function getWinnersAttribute()
{
return $this->with('users')->where("Finals","=",1)->limit(3)->orderBy("final_place","asc")->get();
}
This return "Winners" attribute empty:
public function getWinnersAttribute()
{
return $this->with("users")->where("Finals","=",1)->limit(3)->orderBy("final_place","asc");
}
I've created $appends variable to apply the accessor: protected $appends = ['Winners'];
However, I've checked the accessor, it works. If I return just:
public function getWinnersAttribute()
{
return "123";
}
it works fine and I get "123" inside "winners" attribute of main query result.
The main query is:
Tournaments::with(['users'])->get();
The Finals column is in pivot table of Many-To-Many relation.
UPDATED:
When I try to return query to that Model without relation:
public function getWinnersAttribute($value)
{
return $this->where("Finals",'=',2);
}
I get nothing in winners attribute as well. Like the subquery is not executed.
And if I add get() in the end of return:
return $this->where("Finals",'=',2)->get();
I get blank white page.
How can I solve that problem?
Thanks a lot.
If the getWinnersAttribute is on the Tournament model that means you already have a Tournament model you are calling by doing for example Tournament::find(1)->winners In your attribute you are trying too find the model again, and that could make it a forever loop trying to find a new one already having one etc. try using $this instead
public function getWinnersAttribute()
{
return $this->where("finals","=",1)->limit(3)->orderBy("final_place","asc")->get();
}

Relation 3 tables (laravel 5.7)

I have 3 table like this image. I want get specify pet with race and get owner of this pet. How can i get all the three records from pets.
I have try
Pets::find($id)->races()->with(users)->get();
public function users()
{
return $this->hasMany('App\User', 'id');
}
public function races()
{
return $this->hasMany('App\Races', 'id', 'id');
}
Thx for help
Usually when you have a [something]_id it indicates the row belongs to another row.
Change the relationships in your Pets model to be:
public function user()
{
return $this->belongsTo('App\User');
}
public function race()
{
return $this->belongsTo('App\Races');
}
Then to get the user and race you can do:
Pets::with('user', 'race')->find($id);
or since you're only getting loading the one Pet here you can simply do:
$pet = Pets::find($id);
and you will have access to $pet->user and $pet->race anyway.
if you have pets model you should add belong to user and also belong to pets_reces in it
and try Pets::find($id)->races;
or Pets::find($id)->users;
another way is to get user id or race id and then get all pets from it with out create model for pets so you can add belong to many in users and races.

Using group by and count with laravel eloquent

I have a Forum and Forum Response Model with following database tables:
forum.id
forum_response.id
forum_response.forum_id
forum_response.user_id
forum_response.text
The Forum Model relationship is:
public function responses()
{
return $this->belongsToMany(ForumResponse::class, 'forum__responses');
}
and the Forum Response relationship:
public function Forum()
{
return $this->belongsTo(Forum::class);
}
I would like to get the number of unique responses for a specific Forum, grouped by the user_id. I have tried the following return $this->hasMany(ForumResponse::class)->groupBy('user_id')->count(); but this is returning a higher value than I'm expecting.
Even though, I feel you have something wrong in your structure. But for now, you have an error in your relationships. Just change belongsToMany to hasMany
change this
public function responses()
{
return $this->belongsToMany(ForumResponse::class, 'forum__responses');
}
to this
public function responses()
{
return $this->hasMany(ForumResponse::class, 'forum__responses');
}

Retrieving a single colum from a pivot table - Laravel 5

I am using a pivot table genre_user to relate user to genre.
table contains the following fields
id
user_id
genre_id
Following are the model definitions
User.php
public function genres() {
return $this->belongsToMany('App\Genre');
}
Genre.php
public function artists() {
return $this->belongsToMany('App\User');
}
I am getting the results as a collection when I use the following code
$user = auth()->user();
dd($user->genres);
I want to show the selected genres in a dropdown field of genres. Is it possible to get only the current users genre_id as an array from the pivot table without using a foreach loop.
I think what will help you achieve this behavior is the lists() method.
Try something like
$user_genres = auth()->user()->genres()->lists('name','id');
If you are using Forms & HTML package you can just do
{!! Form::select('genres',$user_genres,null) !!}
And here is your dropdown
More info here (scroll down to "Retrieving A List Of Column Values")
A user should have one genre.
Therefore, your models should contain the following relations:
User.php
public function genre() {
return $this->hasOne('App\Genre');
}
Genre.php
public function artists() {
return $this->belongsToMany('App\User');
}

Categories