laravel belongstomany same table error: Not unique table/alias. Help me please.
class Categories extends Model
{
use HasFactory;
protected $fillable = [
'name',
'parent_id',
'slug',
'title',
'description'
];
public function categories(){
return $this->belongsToMany(Categories::class, 'categories', 'id', 'parent_id' );
}
}
Without second table you can have many-to-many relationship. You may try one-to-many with something like this:
class Categories extends Model
{
/* ... */
public function parentCategory() {
return $this->belongsTo(Categories::class, 'parent_id' );
}
public function subCategories() {
return $this->hasMany( Categories::class, 'parent_id');
}
}
Related
I have problem with search in json column.
I have 3 relations:
products
feature products
feature_values
My tables:
products: https://ibb.co/1dgjT6m
feature products: https://ibb.co/K9f74Wn
feature_values: https://ibb.co/rc3zG5W
My migrations:
Product:
class Product extends Model implements Presentable
{
....
public function featureProducts()
{
return $this->hasMany(FeatureProduct::class, 'product_id');
//return $this->belongsToMany(Feature::class, 'feature_product', 'id');
}
}
FeatureProduct
class FeatureProduct extends Model
{
protected $table = "feature_product";
protected $with = [
'values'
];
public function values()
{
return $this->belongsTo(FeatureValue::class, 'feature_values_ids', 'id');
}
}
FeatureValues:
class FeatureValue extends Model
{
use SoftDeletes,
Translatable;
protected $fillable = [
'feature_id',
'value'
];
protected $dates = [
'created_at',
'updated_at',
'deleted_at'
];
protected $translatable = [
'value'
];
public function feature(): BelongsTo
{
return $this->belongsTo(Feature::class);
}
public function getAdminUrlAttribute(): AbstractAdminUrlPresenter
{
return new FeatureValueUrlPresenter($this);
}
}
I need to show products with features and assigned features_values
I heve problem with search in json column: feature_product. feature_values_ids
When I have INT in this column, then this is working fine:
public function values()
{
return $this->belongsTo(FeatureValue::class, 'feature_values_ids', 'id');
}
When I have:
["1", "2","3"]
I haven't any results :(
Haw can I repair it?
I have 3 Model
In Purchase Model
protected $fillable = [
'name', 'date', 'description', 'active', 'supplier', 'total', 'paid', 'purchase_status', 'payment_status',
];
public function product()
{
return $this->belongsTo(\App\Product::class);
}
public function order()
{
return $this->belongsTo(\App\Order::class);
}
In Order Model
protected $fillable = [
'name', 'quantity', 'unit_cost', 'discount', 'tax', 'sub_total'
];
public function order_items()
{
return $this->belongsTo(\App\OrderItem::class);
}
In my OrderItem Model
protected $fillable = ['active', 'description', 'quantity', 'discount', 'unit_price'];
public function order()
{
return $this->belongsTo(\App\Order::class);
}
Is it possible to query Order_Items From Purchases trough Orders Relationship in Laravel?
Oh, i found my answer...
In Order Model
i changed belongsTo to hasMany
protected $fillable = [
'name', 'quantity', 'unit_cost', 'discount', 'tax', 'sub_total'
];
public function order_items()
{
return $this->hasMany(\App\OrderItem::class);
}
Yes you can write this relations in your models and write the query like this:
Purchase
public function order()
{
return $this->belongsTo('App\Models\Order', 'order_id', 'id');
}
Order_Item
public function order()
{
return $this->belongsTo('App\Models\Order', 'order_id', 'id');
}
Order
public function order_items()
{
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
public function purchases()
{
return $this->hasMany('App\Models\purchase', 'order_id', 'id');
}
Now you can use this query:
$purchase = \App\Models\Purchase::first();
$order_items = $purchase->order->order_items;
I see that you've fixed the relationship Order -> OrderItem of belongsTo to hasMany. But the question was also about how to query through relationships so I'll just add up to this so it could be useful to other users here.
Now you could do
$order_items = $purchase->order->order_items
to get the order items of the purchase.
However you should consider that this would execute further queries to the DB. One for fetching the order and then another one for fetching the order_items. If you're looping through a list of purchases, this could escalate quickly and end up making too much DB queries and affect the performance of your application.
The solution is eager loading.
You could do either pre-fetch the order and items along with the purchase like this:
$purchase = Purchase::with('order.order_items')->find(1);
or if you've already fetched the purchase, then you could do:
$purchase->load('order.order_items');
Then when getting the order items in your code like this
$purchase->order->order_items, you have no additional queries to the DB.
I have three tables post,user and country.
Post is saved by user who is from a country.
Now I want to search all posts of all users from a country.
so user will filter by country and I get country code from search box to controller $request->input($country);
Here are my model relationships:
POST MODEL:
class Post extends Model
{
protected $table = 'posts';
protected $dates = ['status_change'];
public function photos()
{
return $this->hasMany(Photo::class,'post');
}
public function make_rel()
{
return $this->belongsTo(Make::class, 'make_id' ,'id','make_logo');
}
public function user_rel()
{
return $this->belongsTo(User::class, 'created_by' ,'id');
}
}
COUNTRY MODEL:
class Country extends Model
{
public function users(){
return $this->hasMany('App\User');
}
}
USER MODEL:
class User extends Authenticatable
{
public function country_rel()
{
return $this->belongsTo(Country::class, 'country' ,'country_code');
}
}
SEARCH FUNCTION
public function search(Request $request)
{
$this->validate($request, [
'country' => 'required',
]);
$country = Country::where('country_name',$request->input('country'))->get();
$data = Post::where('created_by',$country->user_rel->name)
->get();
dd($data);
}
This is not working. Could anyone advise what am I doing wrong?
I would use hasManyThrugh. The documentation even uses your exact use case:
class Country extends Model
{
public function users(){
return $this->hasMany('App\User');
}
public function posts() {
return $this->hasManyThrough(
'App\Post',
'App\User',
'country_id', // Foreign key on users table...
'user_id', // Foreign key on posts table...
'id', // Local key on countries table...
'id' // Local key on users table...
);
}
}
I am building a small application in Laravel where I got stuck with the sum of inner relational data,
I have a model Company which has Many relation associatedProjects and associatedProjects belongs to relation project and project hasOne technicalDescription.
Company Model:
class Company extends Model {
public function roles()
{
return $this->belongsToMany('Noetic\Plugins\Conxn\Models\Variables\Company\Role', 'company_role_relation', 'company_id', 'role_id')->withTimestamps();
}
public function specialisations()
{
return $this->belongsToMany('Noetic\Plugins\Conxn\Models\Variables\Company\Role', 'company_specialisation_relation', 'company_id', 'specialisation_id')->withTimestamps();
}
public function associatedProjects()
{
return $this->hasMany('Noetic\Plugins\Conxn\Models\Project\AssociateCompany','company_id','id');
}
}
AssociateCompany Model:
class AssociateCompany extends Model {
protected $table = 'project_associate_company';
protected $fillable = [
'project_id', 'company_role_id', 'company_specialisation_id', 'company_id', 'link', 'file_name'
];
public function project()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Project','project_id','id');
}
public function company()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Company','company_id','id');
}
public function companyRole()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Variables\Company\Role',
'company_role_id','id');
}
public function specialisation()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Variables\Company\Role',
'company_specialisation_id','id');
}
}
Project Model
class Project extends Model {
protected $fillable = [
'user_id','koshy_id', 'name', 'slug', 'owner_spv', 'spv_link', 'latitude', 'longitude',
'landmark', 'city', 'district', 'state', 'pin_code', 'region_id', 'country', 'building_use',
'sector', 'conxn_id', 'parent_project_id', 'website', 'project_logo', 'tracked', 'verified',
'code_link', 'status', 'active', 'premium','area'
];
public function technicalDescription()
{
return $this->hasOne('Noetic\Plugins\Conxn\Models\Project\TechnicalDescription','project_id','id');
}
public function associateCompany()
{
return $this->hasMany('Noetic\Plugins\Conxn\Models\Project\AssociateCompany','project_id','id');
}
}
Now this technicalDescription has fields construction_cost, now I want to first count total number of associatedProject and fetch sum of all the project's construction_cost which is in technicalDescription, some what I have done this code:
$company = Company:: where( 'status', 'saved')
->withCount( 'associatedProjects' )
->with('associatedProjects.project.technicalDescription')
->get()
->transform(function ($value) {
$value['project_value'] = $value['associatedProjects']->flatten(2)
->pluck('project.technicalDescription')->sum('construction_cost');
return $value;
})
->sortByDesc('project_value')
->forpage( $request->page , 10 );
$next = $request->page+1 ;
$previous =$request->page-1 ? abs($request->page-1):1 ;
I am unable to use paginate over here as laravel collection doesn't have such method, moreover the query logic also doesn't appear accurate.
Any suggestions are welcome. Thanks
You can use a BelongsToMany relationship to get the technicalDescriptions directly:
class Company extends Model {
public function technicalDescriptions() {
return $this->belongsToMany(
'Noetic\Plugins\Conxn\Models\Project\TechnicalDescription',
'project_associate_company',
'company_id',
'project_id',
null,
'project_id'
);
}
}
$company = Company::where('status', 'saved')
->withCount(['technicalDescriptions as project_value' => function($query) {
$query->select(DB::raw('sum(construction_cost)'));
}])
->orderByDesc('project_value')
->paginate();
In my model i added protected $table, but when i'm going to use it laravel does't use it. This is my role models:
class Role extends Model
{
protected $table = 'role';
protected $primaryKey = 'ROLE_ID';
protected $casts = [
'ACTIVE' => 'boolean',
];
protected $fillable = [
'ROLE', 'ACTIVE', 'TYPE'
];
public $timestamps = false;
public function groups()
{
return $this->belongsToMany(Group::class, GroupRole::class, 'ROLE_ID', 'GROUP_ID');
}
}
And this is Group model:
class Group extends Model
{
protected $table = 'groups';
protected $primaryKey = 'GROUP_ID';
protected $fillable = [
'GROUP_ID', 'GROUP_NAME', 'PARENT_GROUP', 'ACTIVE'
];
protected $casts = [
'ACTIVE' => 'boolean',
];
public $timestamps = false;
public function type()
{
return $this->belongsTo(GroupType::class, 'TYPE', 'TYPE_ID');
}
public function roles()
{
return $this->belongsToMany(Role::class, GroupRole::class, 'GROUP_ID', 'ROLE_ID');
}
}
And this is group_role table model. It handles many to many relation between role and group:
class GroupRole extends Model
{
protected $table = 'group_role';
protected $primaryKey = 'GROUP_ROLE_ID';
protected $fillable = [
'COMMENT', 'ROLE_ID', 'GROUP_ID'
];
public $timestamps = false;
}
Problem begin when i want to use this models. For example:
$role = App\Role::first();
$groups = $role->groups;
Laravel returns this error messages:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'favian_mydb.App\GroupRole' doesn't exist (SQL: select groups.*, App\GroupRole.ROLE_ID as pivot_ROLE_ID, App\GroupRole.GROUP_ID as pivot_GROUP_ID from groups inner join App\GroupRole on groups.GROUP_ID = App\GroupRole.GROUP_ID where App\GroupRole.ROLE_ID = 1)
I tried to replace App\GroupRole with group_role and executing in mysql. It works fine. Am i missing something?
The Problem is in your roles relation:
public function roles()
{
return $this->belongsToMany(Role::class, GroupRole::class,'GROUP_ID','ROLE_ID');
}
The belongsToMany expects the intermediate table name as second argument, not the class name.
So you have to define it like this:
public function roles()
{
return $this->belongsToMany(Role::class, 'group_role','GROUP_ID','ROLE_ID');
}
I think the problem is in you relation functions. Try to use strings instead of Model::class.
Example:
return $this->return $this->belongsTo('App\GroupType', 'TYPE', 'TYPE_ID');
Hope this works.