So I have this model, 'Ticket' that contains (among other things) a "category_id" column.
To simplify, here is how my datas look:
Tickets table
id
Title
category_id
1
Issue #1
2
2
Issue #2
4
3
Issue #3
1
Categories table
id
Title
1
Authentication
2
Account
3
Billing
In my Ticket model, I've done the following:
/**
* #return Category
*/
public function category(): Category
{
return Category::firstWhere($this->category_id);
// return $this->belongsTo('App\TicketCategory'); <-- how it was, can't eager load.
}
But I'm getting an undefined function addEagerConstraints().
Edit: here is my controller:
class TicketController extends Controller
{
public function index()
{
$tickets = Ticket::with('category')->all();
// dd($tickets);
return view('tickets.index', compact('tickets'));
}
}
I also tried with hasOne but this implies that "categories" needs a "ticket_id" column, which I want to avoid.
I'd like my models just to pick the category they are related to and nothing more.
What would be a solution here?
Thanks in advance
In your category model, have the following code:
public function tickets()
{
return $this->hasMany(Ticket::class);
}
And add this in the ticket model:
public function category()
{
return $this->belongsTo(Category::class);
}
Add in the PHP 8 stuff you have already, and it should work!
Edit:
I saw you added more about how to load this properly. The code you already have in your controller should work with this as well. You'll maybe need to change the model class names in the methods I provided, but that should do the trick!
For more information about this type of relationship (one to many) read this part of the documentation.
Related
I have 2 models: Company and Category
Company has many Categories, and Category belongs to Company
// App\Models\Company.php
public function categories()
{
return $this->hasMany(Category::class);
}
and
// App\Models\Category.php
public function company()
{
return $this->belongsTo(Company::class);
}
All ok with relationship, now I have a route
/company/{company}/category/{category}
And in the controller I have the next code:
public function foo(Company $company, Category $category)
{
///
}
And I get a 404 not found. I think it is because the relationship between Company and category fails.
If I do the next:
public function foo($company, Category $category)
{
dd(
Company::find($company)->categories()->where('id', $category->id)->first(),
$category
);
}
I get the correct Category in both way, so, the relationship in model I guess is ok. Also, I can add/remove with relationship, so again, I guess is ok.
Now, my question is, how I can inject 2 model with relationship in the controller?
Cuz all way I'm getting error 404.
Thanks!
I have 3 tables:
Users
Baskets
Items
id
id
id
user_id
basket_id
price
I'm trying setup a relationship in eloquent by which I can get all the all the Items and the corresponding Baskets where the price of items is X. I want it so that I can simply use $user->items(x) and get the results.
I'm unsure if this can be done using Relationships alone or will I have to resort to writing custom queries.
Any, and all, help and guidance will be appreciated!
The relationship you are looking for is hasManyThrough
https://laravel.com/docs/7.x/eloquent-relationships#has-many-through
User Modal
public function items()
{
return $this->hasManyThrough(Item::class, Bucket::class);
}
The way you want to use is not possible to achieve I think.
Possible Usage
$user->items()->where('price', x);
of if you define custom scopes
Item Modal
public function scopeWherePrice($query, $value)
{
return $query->where('price', $value);
}
Usage
$user->items()->wherePrice(x);
EDIT
If you really want to write a code like $user->items(x) you can define a method on the User Modal.
Note that this is not a relationship, just another method which fetch the result.
User Modal
public function items($price)
{
return this->items()->where('price', $price)->get();
}
Using hasManyThrough Define the relationship in your models:
User Model
/**
* Get all of the items & baskets for the user.
*/
public function items($price)
{
return $this->hasManyThrough('App\Items', 'App\Baskets')
->with('basket')
->where('price',$price);
}
Basket Model
/**
* Get the Items's Basket.
*/
public function basket()
{
return $this->belongsTo('App\Basket','basket_id');
}
And then call it like this:
$user->items(x);
This will return all user items with their corresponding baskets in a specific price.
The idea is that I have relation between two table's section and user
the section_id exist in users table it relation with id section
SO for ex : section_id = 2 > want to bring all users belongs to id section
My code here use id from url and I don't want to do this I want without id bring all users :
public function getAllUsers($id)
{
$data = User::where('section_id',$id)->get();
}
If I'm understanding you correctly, you want to get all the users for a particular Section that have the relationship to that section.
Assuming you have the relationship set up correctly on the Section model:
public function users() {
return $this->hasMany('App\User');
}
I suggest you go about this 'backward' and just pull the users from the Section model itself (eager loading allows one query):
$section = Section::with('users')->first();
$usersForThisSection = $section->users;
If you setup a One to Many relationship you can say things like: $user->section to return the section a user belongs to...and $section->users to get a collection of all the users in a section -- the getAllUsers() is redundant in this case.
Make sure your User and Section models contain these methods. Sounds like your migration was setup properly if you have a section_id column on your users table.
More info on one-to-many here: https://laravel.com/docs/5.8/eloquent-relationships#one-to-many
// app/User.php
class User extends Model
{
public function section() {
return $this->belongsTo('App\Section');
}
}
// app/Section.php
class Section extends Model
{
public function users() {
return $this->hasMany('App\User');
}
}
Test out your relationships in php artisan tinker like so...
$user = User::find(1);
$user->section
$section = Section::find(1);
$section->users
you need a unique identifier to receive section_id's users. receive it from url(get) or ajax(post) . if you worry about users access then use "auth"
I have 3 tables schools, school_Details,ratings
** Schools**
id
name
phone
school
email
status
School details:
-id
school_id
image
status
ratings:
-id
school_id
rating_value
status
both rating &school details have only one row for one school_id.
Now how can i get all details from all 3 tables in index from schoolController
Use Laravel Relationship.
In Schools Model add this.
public function schoolDetails()
{
return $this->hasOne('App\SchoolDetails');
}
public function ratings()
{
return $this->hasOne('App\Ratings');
}
In School Details Model add this.
public function school()
{
return $this->belongsTo('App\School');
}
In Ratings Model add this.
public function school()
{
return $this->belongsTo('App\School');
}
In School Controller
public function index()
{
$schools = Schools::with('schoolDetails')
->with(ratings)
->get();
return $schools;
}
Can you try this,
This is a pretty wide question. It would help to show what you've tried so far. The answer is to create one to many relationships from schools to details and ratings.
And then call those relations within the base school object from your index method. You can even eager load these for one simple and clean pull from the database.
To clarify, from your School model:
public function ratings()
{
return $this->hasMany('App\Rating');
}
And same thing for your school details. Then, to eager load in your index method:
$schools= App\School::with(['ratings', 'details'])->get();
Then your school object has all you've asked for:
$school->ratings->status
etc.
I have model many to many relation like. I want to relate State and Category through pivot table CategoryNews.
Category model
class Category extends Model
{
public function news() {
return $this->belongsToMany('App\News');
}
}
News model
class News extends Model
{
public function categories()
{
return $this->belongsToMany('App\Category');
}
public function state()
{
return $this->belongsTo('App\State');
}
}
and the State model
class State extends Model
{
public function news() {
return $this->hasMany('App\News');
}
}
I want to select the news related to the state where cat_type=2(from category table)
i tried
$slide_news = State::whereHas('news.categories',function($query){ $query->where('categories.cat_type',2);})
->with(array('news'=>function($query){
$query->orderBy('created_at', 'desc');}
))->where('id',$id)->first();
but the cat_type filter is not working. I also tried hasManyThrough but i don't know how to implement it with Pivot Table
Please help
There is a Laravel 5.5 composer package that can perform multi-level relationships (deep)
Package:
https://github.com/staudenmeir/eloquent-has-many-deep
Example:
User → belongs to many → Role → belongs to many → Permission
class User extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function permissions()
{
return $this->hasManyDeep(
'App\Permission',
['role_user', 'App\Role', 'permission_role'], // Pivot tables/models starting from the Parent, which is the User
);
}
}
Example if foreign keys need to be defined:
https://github.com/staudenmeir/eloquent-has-many-deep/issues/7#issuecomment-431477943
To the moderators:
DO NOT DELETE MY ANSWER
It took me two god damn days to solve this issue, and I was so happy i found the solution that i want to let the world know
Notice that my answer was upvoted, yet you deleted it.
The question's title is regarding: hasManyThrough Pivot table for Laravel, and my answer gives just that, a solution to perform hasManyThrough equivalent on Pivot Tables
The question was 3 years old, and let's admit no one wants a solution specific to the question, because we've all got our own.
If I were you, I'd prefer a generic answer.