Laravel pivot table with 3 relationships - laravel

I'm trying to figure out how to set up my relationship using a pivot table with three different relationships.
users
- id
- username
products
- id
- name
tags
- id
- user_id
- name
user_products
- user_id
- tag_id
- product_id
When using the "Product" model, I would like to be able to pull all the associated tags. I'm currently able to pull the "user_products" object, but I would like to know how to pull the actual tag object in stead.
Models:
class User {
public function tags()
{
return $this->hasMany('UserTag');
}
}
class Product {
public function user()
{
return $this->belongsTo('User','user_products','product_id','user_id');
}
public function tags()
{
????
}
}

return $this->belongsTo('User','user_products','product_id','user_id')
->withPivot('tag_id')
->join('tags', 'tags.id', '=', 'user_products.tag_id')
->select(...);
Something like this should work fine.

Related

I want to make many to many relationship using laravel Model

I am trying to make many to many relationships b/w three table I don't know how to make that please confirm me my relationship correct or not.
Project table
id | name
user table
id | name
project_assign
id | user_id | project_id
User Model
public function project_assign()
{
return $this->belongsToMany('App\Project_assign','project_assign','user_id','id');
}
project_assign Model
public function user()
{
return $this->belongsToMany('App\User','Project_assign','user_id','id');
}
Project Model
public function project_assign()
{
return $this->belongsToMany('App\Project_assign','project_assign','project_id','id');
}
you don't need to make a relation in project_assign model. only Project and User will have relation,
Project Model
public function users(){
return $this->belongsToMany('App\User','project_assign','project_id','user_id');
}
User Model
public function projects(){
return $this->belongsToMany('App\Project','project_assign','user_id','project_id');
}
In controller you can get like this
User::with('projects')->get();
Project::with('users')->get();

Accessing 3 tables in Laravel using foreign key (laravel 6)

I want to show data from a database(sql) that is from a specific user.
I have 3 tables:
Users
Stores
Areas
These are the following relationship between tables:
User hasOne Area
Area hasMany Stores
Basically what I wanted to show is that every user has their own area that has many stores.
User model
function area() {
return $this->hasOne('App\Area');
}
Area model
function user() {
return $this->belongsTo('App\User');
}
function stores() {
return $this->hasMany('App\Store');
}
Store Model
function area() {
return $this->belongsTo('App\Area');
}
My database looks like this:
user table
id name role_id area_id
area table
id name user_id
store table
id name area_id
How can I access user->area->store?
This is what I got so far
function show() {
$id= Auth::user()->id;
$user = User::find($id);
echo($user->area->stores);
}
Thank you
you can use the hasManyThrough for get sotres of an area:
define stores function in User model
public function stores()
{
return $this->hasManyThrough(Store::class, Area::class);
}
and use it :
$stores = auth()->user()->stores;
I hope be useful.

Laravel | Using Eloquent hasManyThrough

I have a table called invoiceDetails that has item_id as foreign key from another table called items which has category_id as foreign key from table called categories.
I want to do that following using eloquent:
$result = InvoiceDetail::groupBy('item_id')
->selectRaw('sum(qty) as qty, item_id')->with('item', 'category')->get();
but I am getting error:
Call to undefined relationship [category] on model [App\InvoiceDetail].
Here's my relation inside Category model:
public function invoiceDetail() {
return $this->hasManyThrough('App\InvoiceDetail', 'App\Item', 'category_id', 'item_id');
}
Any suggestions?
Not sure you would even need a hasManyThrough relation here, unless you want to fetch all InvoiceDatail objects belonging to all items which in turn belong to the Category. That part is not clear from your question.
But in your example you are fetching items with their category from distinct item_id.
The reason this is not working is because you are trying to fetch the category relation from the InvoiceDetail object, which does not exist.
->with('item', 'category')
You want to load the Category based on the item relation, not based on the InvoiceDetail, try the dot notation (given that you did define the other relations)
->with('item.category')
Relations should be like this:
class InvoiceDetail extends Model
{
public function item()
{
return $this->belongsTo(\App\Item::class);
}
}
class Item extends Model
{
public function invoiceDetails()
{
return $this->hasMany(\App\InvoiceDetail::class);
}
public function category()
{
return $this->belongsTo(\App\Category::class);
}
}
class Category extends Model
{
public function items()
{
return $this->hasMany(\App\Item::class);
}
public function invoiceDetails()
{
return $this->hasManyThrough(\App\InvoiceDetail::class, \App\Item::class, 'category_id', 'item_id');
}
}
You would want to use the hasManyThrough if, for example, you have a Category and you want to load all the InvoiceDetails directly.
dd($category->invoiceDetails);

Laravel - How to setup a morphOne relationship

I'm trying to implement a morphable table for categories, right now I've the following.
// Snippet Table
- id
- title
- body
// Post Table
- id
- title
- body
// Category Table
- id
- name
I want to be able to morph the posts and snippets to have only one category, something like this:
// Categorizable Table
- category_id
- categorizable_id
- categorizable_type
Do I have to have another model for this categorizable table? Or there is a way to set it without another model?
So far I have this
class Snippet extends Model
{
public function category()
{
return $this->morphOne(Category::class, 'categorizable');
}
}
class Post extends Model
{
public function category()
{
return $this->morphOne(Category::class, 'categorizable');
}
}
class Category extends Model
{
public function categorizable()
{
return $this->morphTo();
}
}
And I have 4 tables, snippets, posts, categories, categorizables, the last one the migration looks like this.
Schema::create('categorizables', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('category_id');
$table->morphs('categorizable');
$table->timestamps();
});
The thing is, what is the correct way to save this relationship, I'm testing it on tinker and bothattach($category_id) and sync($category_id) aren't saving the relationship they return the error BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::categorizable()', What I'm missing?
Sorry I thought you wanted many-to-many relationship. morphOne relationship API is the same as morphMany from the docs
Post extends Model
{
public function category() {
return $this->morphOne(Category::class, 'categorizable');
}
}
Category extends Model
{
public function categorizable() {
return $this->morphTo();
}
}
EDIT
When using morphOne you don't need a pivot table categorizables table must be deleted and change your categories table to include the morph fields
// Category Table
- id
- name
- categorizable_id
- categorizable_type

Laravel hasManyThrough getting through another model

I have this 3 tables. I would like to get the employee name who created the client
I have tried this
class LeadsModel extends Eloquent
public function researcher_name()
{
$user = $this->belongsTo('users','id','user_id');
return $user->getResults()->belongsTo('employees','id','employee_id');
}
But it returns an error:
"message":"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'employees.employee_id' in 'where clause' (SQL: select * from `employees` where `employees`.`employee_id` in (4))"}}
when I switch the id and employee_id, it does not return any relationship for users and employees.
Basically, I need to get the clients with the employee's name who created it.
Assuming relationships:
Client belongsTo User
User belongsTo Employee
simply call this:
$client->user->employee;
Given your schema, here are the relations you need in order to get an Employee related to particular Client (through User):
// Client model
public function user()
{
return $this->belongsTo('User');
}
// User model
public function employee()
{
return $this->belongsTo('Employee');
}
then simply call this:
$client = Client::find($someId);
$client->user; // single user related to the client
$client->user->employee; // single employee related to the user
You might want to check if given relation exists first:
// just an example, don't write it this way ;)
if ($client->user) { // user is not null
if ($client->user->employee) { // employee is not null as well
$client->user->employee->name; // name = field on the employees table
}
}
You need a Has Many Through relation.
Add the relationship in your Employee's model called clients:
public function clients()
{
return $this->hasManyThrough('App\Client', 'App\User');
}
And then you can use it like below:
Employee::first()->clients()->get();

Resources