I have some models in my project with differents relations detailed in this picture:
I created some models to represents each tables.
And I would to know if there is a possibility to create relationship that allows to recover all the students of teachers or all the teachers of students.
Example:
class Student extends Model
{
public function clases(){
return $this->hasMany(Clase::class, 'student_id');
}
/** This function doesn't works, not the great relation */
public function teachers(){
return $this->hasManyThrough(Clase::class, Teacher::class, 'student_id', 'teacher_id');
}
}
I'm using Laravel 5.8
Thank in advance
You can use Clase as a pivot table to define a many-to-many relation:
In your Student class (assuming 'clase' to be the table name):
public function teachers(){
return $this->belongsToMany(Teacher::class, 'clase', 'student_id', 'teacher_id');
}
Because this is a special relation, you need to define all foreign keys, they are perfectly described in the documentation.
I think this would work for you:
return $this->hasManyThrough(
Teacher::class,
Clase::class,
'student_id',
'user_id',
'user_id',
'teacher_id'
);
Related
What is the best practice to setup many to many relationship with post and categories in laravel eloquent? Do I create a separate model for pivot table?
This is how I defined it in post model.
public function category()
{
return $this->belongsToMany('App\Category');
}
you need to change the relationship method name to categories()
/**
* The categories that belong to the product.
*/
public function categories()
{
return $this->belongsToMany('App\Category', 'category_product');
}
category_product - is your pivot table, you can define if you change the naming convention or its optional.
In Category model, you can define it like blow
/**
* The users that belong to the role.
*/
public function products()
{
return $this->belongsToMany('App\Product', 'category_product');
}
If you require you can create a model for pivot table, in my case this is how i store data to pivot table (using attach method)
$product->categories()->attach($category); //list of category id's
And you can update it again using detach method or synch method.
$product->categories()->sync($synch); // new category id's
The best way to do this is:
public function categories(){
return $this->belongsToMany('App\Models\Categories', 'categories_posts', 'post_id', 'category_id');
}
And then in your Categories model:
public function posts(){
return $this->belongsToMany('App\Models\Posts', 'categories_posts', 'category_id', 'post_id');
}
belongsToMany() method can receive up to 4 parameters, the first one is the location of your model to link, the second is the name of the pivot table, the third one is the current model foreign key and the fourth one is the other's model foreign key.
You can also specify extra data on pivot table using the withPivot() method like this for example:
public function categories(){
return $this->belongsToMany('App\Models\Categories', 'categories_posts', 'post_id', 'category_id')->withPivot('quantity');
}
And then for attaching you can do as follows:
$post = Posts:find(1);
$post->categories()->attach($category_id, ['quantity' => 2]);
But please, refer to Laravel's official documentation:
https://laravel.com/docs/5.6/eloquent-relationships
To define this relationship, three database tables are needed: post, category, and category_post. The category_post table is derived from the alphabetical order of the related model names, and contains the category_id and post_id columns.
I've got Tag and Attendee Eloquent models, they are in many-to-many relation. Pivot table has also two more attributes – value_int and value_string. My Attendee model looks like this:
class Attendee extends Model
{
public $timestamps = false;
protected $fillable = [
'event_id'
];
public function tags() {
return $this->belongsToMany('App\Models\Tag', 'attendee_tag', 'attendee_id', 'tag_id')
->withPivot(['value_string', 'value_int']);
}
public function scoreTagValue($tag_id) {
return $this->tags->where('tag_id', '=', $tag_id)->first();
}
}
What I want is to obtain pivot values based on Attendee model and variable tag_id, so I've written scoreTagValue function, but it always returns null and I don't know why :( I'm calling it this way:
$attendee->scoreTagValue($tag_id). Thanks for your help :)
You need to access the relation, not the property:
public function scoreTagValue($tag_id) {
return $this->tags()->where('tag_id', '=', $tag_id)->first();
}
Also, according to the docs, withPivot() does not take an array, so:
->withPivot('value_string', 'value_int');
Hi I need to display users items from table name Items.
I have 3 models.
User model:
public function userItem()
{
return $this->hasMany('App\UserItem', 'item_id');
}
UserItem model:
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
What to write to Item Model to make this relationship successful. So I could display items from items table.
If I now do this:
I get info from user_items table from DB.
when I do this #foreach(Auth::user()->userItem as $item) I get this:
Column not found: 1054 Unknown column 'user_items.user_items' in
'where clause'
I think you want to use many to many relation
you have 2 models User and Item
and 3 tables : -users -items -user_items
User Model should be like this:
public function userItem()
{
return $this->belongsToMany('App\Item','user_items','user_id','item_id');
}
and Item Model:
public function user()
{
return $this->belongsToMany('App\User','user_items','item_id','user_id');
}
and you need a table that you named it user_items
and you dont need to define userItem model you can remove relations in this model
in your blade use this code:
#foreach(Auth::user()->userItem as $item)
You are exhibiting a many-to-many relatioship, and yet using methods for one-to-many relationships. For a many to many relationship, use the following code in your models:
//user model:
public function userItem()
{
return $this->hasMany('App\UserItem', 'user_items', 'user_id', 'item_id');
}
//userItem Model:
public function user()
{
return $this->hasMany('App\User', 'user_items', 'item_id', 'user_id');
}
For a many-to-many relationship, you need a hasMany method on both your models.
For information on the parameters to the hasMany method as well as other information on many-to-many relationships, please read the documentation on many-to-many relationships: https://laravel.com/docs/5.4/eloquent-relationships#many-to-many
Hope this helps.
Not sure why it's now working for me.
I have two tables
events
- id
selections
- id
- event_id
From my Event model I want to relationship selections
class Event extends Model
{
...
public function selections()
{
return $this->belongsTo(Selection::class, 'event_id', 'id');
}
}
My problem is that $event->selections relationship is not working. Keep getting null back.
With the database schema, it is hasMany relation instead.
public function selections()
{
return $this->hasMany(Selection::class, 'event_id', 'id');
}
See One to many relationship in documentation.
I have an Order model and a Service model.
An order can be deleted (soft delete).
I want to list all orders, deleted and active and the service that it belongs to.
Order Model:
class Order extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function service ()
{
return $this->belongsTo('Service');
}
}
Service Model:
class Service extends Model
{
public function order()
{
return $this->belongsToMany('Order');
}
}
What I tried:
$company=Company::with('orders.service'=>function ($query) {
$query->withTrashed();
},'services'])->where('id',$company->id)->get();
But this returns no orders (and right now I only have 1 deleted order in my db)
Any ideas?
Thanks!!
you can use
public function order() {
return $this->belongsToMany('Order')->withTrashed();
}
First of all, a belongsToMany relationship always goes with another belongsToMany relationship at the other side, so you are not doing right the relationships.
If you want a many to many relationship, both models should have a belongsToMany relationship to the other model, and you must have a pivot table.
If you want a one to many relationship, one model should have a belongsTo relationship and the other a hasMany relationship.