Laravel Self Relationships - laravel

Well, i have this table in my Database:
CREATE TABLE categories(
id INT,
name VARCHAR,
id_parent INT,
CONSTRAINT fk_categories FOREIGN KEY(id_parent) REFERENCES categories(id)
);
In Laravel Category model, I have this:
class Category extends Eloquent
{
protected $table = "categories";
public function parentCategory(){
return $this->belongsTo("Category","id_parent");
}
public function subCategories(){
return $this->hasMany("Category","id_parent");
}
}
Also I have this data:
id name id_parent
1 category_1 NULL
2 category_2 NULL
3 category_3 1
4 category_4 1
5 category_5 2
When I call in the controller:
count(Category::with("subCategories")->get()); The count returns 5.
And when I call in the controller:
count(Category::has("subCategories")->get()); The count returns 0.
All this is bad, because I want only the categories that parent_id = NULL, that will return to the count 3.
If I use count(Category::where("id_parent","!=","NULL") the result is 3 (it's OK), but I want to get this result by using HAS or WITH function.
So, how can I do this without using "where" function?
Sorry about my English.

Assuming your errors in your code are copy-paste errors (in one places you have parent_id and in others id_parent you cannot do this using has.
It seems a bug for me because wrong query is being executed. I've created Github issue for that, I've seen at least other similar issue.

Related

Laravel recursive relationship return error in query

i have model Hobbies with these relationship
public function sub_hobbies(){
return $this->hasMany(Hobbies::class, 'parent_id')->with('media');
}
public function allsub(){
return $this->sub_hobbies()->with('allsub');
}
in my table hobbies i have data like this
id name parent_id
1 hobbie 1 null
2 hobbie 2 1
3 hobbie 3 2
with my query Hobbies::with('sub_hobbies')->where('parent_id', null)->get(); i get the hobbies with sub_hobbies but there is the third stage, so when using Hobbies::with('allsub')->where('parent_id', null)->get(); i except to have 3 stage of hobbies but i got error 500 without error message
i'm in laravel 8.75.0
EDIT
I found in my log that it make infinite sqlquery, i don't know why it behave like this, i use Mysql if there is something to do with it

$operations = Operation::findOrFail(2)->get(); return 6 results

I'm trying to get the operation that as PK id = 2
$operations = Operation::findOrFail(2)->get();
This line should do the trick, but I get all my 6 operations as result...
Off course, my other 5 has ID value from 1 to 6, they doesn't match.
I checked Operation is a model with no custom config, and Operation table has been created by migration and has ID as PK...
Off course, I could change it with another eloquent query, but this should work and I would love to know why it is failing.
What am I missing ?
remove ->get() it will should be
$operations = Operation::with('meters')->findOrFail(2);
get() gives you a collection which is all data of Operation to get single instace you should remove get()

How to remove and update data on relations table using laravel eloquent?

I have three tables. they are,
users
id name
1 personA
2 personB
3 personC
skills
id name
1 html
2 css
3 javascript
userskills
userid skills_id
2 3
2 1
1 2
1 3
I get the data through the request like [2,1] and the user id 2. On the user skills table in userid 2 there are skills_id3,1. Now i have to remove skills_id 3 and insert skills_id 2 on the userid 2.
How can i achieve it through laravel eloquent method.
As you have a pivot table you can use belongsToMany relationship. Adding the relationship in your User Model
public function skills()
{
return $this->belongsToMany(Skill::class, 'userskills','userid', 'skills_id');
//userskills is the pivot table
}
Now to update use the sync method.
$user = User::findOrFail(2); //your request id
$user->skills()->sync([1, 2]); //request array
This will remove the 3 from the pivot table and add 2 in the table.
Read more about this relationship in here
Your question is little ambiguous but lets assume that you are getting the user id 2 and the skills you want to remove from userskills is 2,1
For deleting
UserSkills::where(['userid' => 2 ])->whereIn('skills_id',[2,1])->delete();
For inserting
UserSkills::create(['skills_id' => 2, 'userid' => 2 ]);
An easier approach using relation would be
$user->skills()->sync([2, 1]);
Sync will remove those skills which are not present in the sync method.

How can I get specific column fields?

I want return specific columns for every card that is returned by eloquent relationship.
I can do it with ->get(['column1', 'column2']) but in this situation I can't use get().
Is there a solution for this ?
$deckId = $request->deckId;
$deck = Deck::find($deckId);
return $deck->cards;
on the cards I want for example just the id the name and the card_type
This code should work if you already defined the relationship
return $deck->cards()->get(['id', 'name', 'card_type']);
Have you looked into pluck?
Deck::all()->pluck('column1', 'column2');
This will return an array with column1 as key and column2 as value

How to add multiple conditions on Laravel elequent relationship

I am new to Laravel and working on 5.4 version. I have a model "A" and model "B". Model A has hasMany relationship with B. Upto here things are ok. But now, I want to add more conditions on this relationship.
By default, Laravel works only foreign key relation. I mean it matches data on the basis of only 1 condition. Here, I want more condition.
Below are the tables of both Model:
table: A
id name Year
1 ABC 2016
2 DEF 2017
table: B
id A_id name Year
1 1 tst 2016
2 2 fdf 2017
3 1 kjg 2017
By default, If I want to see records of A_id 1 from table B, then Laravel will fetch all records for A_id 1. But now, suppose, if I want to get records for 2016 then How I can I do this using Laravel relationship method?
Below are the Elequent Model for both tables:
class A extends Model{
public function b(){
return this->hasMany('B');
}
}
class B extends Model{
public function a(){
return $this->belongsTo('A');
}
}
Code to fetch records of id 1:
$data = A::with('b')->find(1)->toArray();
The above request is giving me all data from table B for id 1 but I also want to put corresponding year condition also.
Is anyone know, Ho can I do this? Please share your solutions.
Thanks
You have to constrain your eager loads, using an array as the parameter for with(), using the relationship name as the key, and a closure as the value:
$data = A::with([
'b' => function ($query) {
$query->where('year', '=', '2016');
},
])->find(1)->toArray();
The closure automatically gets injected an instance of the Query Builder, which allows you to filter your eager loaded model.
The corresponding section in the official documentation: https://laravel.com/docs/5.4/eloquent-relationships#constraining-eager-loads

Resources