Laravel table referencing itself through pivot - php

I have one table called roles:
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description');
$table->string('image')->default("noImage.png");
$table->timestamps();
});
and another table roles_roles
Schema::create('roles_roles', function (Blueprint $table) {
$table->increments('id');
$table->integer("role_id")->unsigned();
$table->integer("role_inherit_from_id")->unsigned();
$table->timestamps();
});
I'd like one role to reference many other roles (to say one role can inherit from multiple others)
public function children(){
return $this->hasMany(Role::class, "roles_roles", "role_inherit_from_id");
but get the error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'roles.roles_roles' in 'where clause' (SQL: select * from `roles` where `roles`.`roles_roles` is null and `roles`.`roles_roles` is not null limit 1)
}`
Does anyone know how to implement a table that can reference itself, or a way to get around this?

Maybe you need belongsToMany instead?
$this->belongsToMany(Role::class, 'roles_roles', 'role_id', 'role_inherit_from_id');
Also, you have wrong syntax hasMany
$this->hasMany(Model::class, 'foreign_key', 'local_key');
Documentatios: belongsToMany, hasMany.

Related

Problems with Where Condition in Pivot Table Laravel 8

Hello I am working on a project, that in this part, to get a dependent dropdown i want to get all the «Areas de Interesse» that are attached to a specific user, getting this, by his ID, that is in the pivot table.
These are my migrations:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->string('profile_photo_path', 2048)->nullable();
$table->timestamps();
});
Schema::create('area_interesse', function (Blueprint $table) {
$table->id();
$table->string('area_interesse');
$table->string('area_interesse_ing');
$table->timestamps();
});
Schema::create('utilizador_interesse', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger("id_utilizador");
$table->foreign('id_utilizador')->references('id')->on('users')->onDelete('cascade');;
$table->unsignedBigInteger("id_interesse");
$table->foreign('id_interesse')->references('id')->on('area_interesse');
$table->timestamps();
});
And my models:
class AreaInteresse extends Model
{
protected $table = "area_interesse";
public function users(){
return $this->belongsToMany(User::class, 'utilizador_interesse', 'id_interesse' , 'id_utilizador');
}
}
class User extends Authenticatable
{
public function interesses(){
return $this->belongsToMany(AreaInteresse::class, 'utilizador_interesse', 'id_utilizador', 'id_interesse');
}
}
In my controller i tried to do this, base on every example i saw, has for testing, i am trying to get all «Areas de Interesse» that are related to the user with id 11
$interesses = AreaInteresse::with('users')
->whereHas('users', function($q){
$q->wherePivot('id_utilizador', 11);
})
->get();
However i am getting this error and i have no idea why it's happening, and why it is assuming i am trying to call a column «pivot»
Illuminate\Database\QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'pivot' in 'where clause' (SQL: select * from `area_interesse` where exists (select * from `users` inner join `utilizador_interesse` on `users`.`id` = `utilizador_interesse`.`id_utilizador` where `area_interesse`.`id` = `utilizador_interesse`.`id_interesse` and `pivot` = id_utilizador))
"I am trying to get all «Areas de Interesse» that are related to the user with id 11"
This is exactly why relationships are defined between models. Just instantiate the user and then get the related models:
$user = User::findOrFail(11);
$interesses = $user->interesses;
As mentioned in comments, and worth repeating here, you should call your class Utilizadore instead of User, or change table and column names to match the name of the class.

Column not found: 1054 Unknown column 'coin_user.symbol' in 'field list'

We have three models (user - currencies - balances) What should be the relationship of these tables, for example, I want to receive the amount of bitcoin currency of user
To do this, I have written the code as follows (according to the help I received from the previous question)
this is user table :
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->enum('type', [User::TYPE_ADMIN, User::TYPE_USER])->default(User::TYPE_USER);
$table->string('name');
$table->string('email')->unique()->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password')->nullable();
$table->timestamp('password_changed_at')->nullable();
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
coin table:
Schema::create('coins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('symbol')->unique();
$table->decimal('buy_percent',6,4)->nullable();
$table->enum('buy_status' , ['active' , 'inactive'])->default('inactive');
$table->text('buy_description')->nullable();
$table->decimal('sell_percent',6,4)->nullable();
$table->enum('sell_status' , ['active' , 'inactive'])->default('inactive');
$table->text('sell_description')->nullable();
$table->timestamps();
});
and balances table. i include pivot table in this migration:
Schema::create('balances', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('coin_id');
$table->string('symbol');
$table->decimal('balance');
$table->timestamps();
});
Schema::create('coin_user', function(Blueprint $table)
{
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedBigInteger('coin_id');
$table->foreign('coin_id')->references('id')->on('coins')->onDelete('cascade');
});
And relationships are written that way:
in User model :
public function coins() {
return $this->belongsToMany(Coin::class)->withPivot(['symbol', 'balance']);
}
in Coin model :
public function users() {
return $this->belongsToMany(User::class)->withPivot(['symbol', 'balances']);
}
and Balance model :
public function coins()
{
return $this->belongsToMany(Coin::class , 'balances');
}
public function user()
{
$this->belongsToMany(User::class , 'balances');
}
when i run this code:
$coin = Coin::with('users')->get();
foreach ($coin as $coin) {
// $coin here is `BTC`, `ETH`, etc.
foreach ($coin->users as $user) {
// $user here is Bob, Mike, etc.
$user->pivot->balance; // 0.16, etc.
// Do whatever with `$coin` and `$user`
}
}
this error returned for me:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'coin_user.symbol' in 'field list' (SQL: select users.*, coin_user.coin_id as pivot_coin_id, coin_user.user_id as pivot_user_id, coin_user.symbol as pivot_symbol, coin_user.balances as pivot_balances from users inner join coin_user on users.id = coin_user.user_id where coin_user.coin_id in (1, 2, 3, 4) and users.deleted_at is null)
What is the problem? How can I access users' balances?
In Laravel, if two models are to have belongsToMany relationship, then a pivot table has to exist for the two models. The absence of a pivot table (assumed so as you did not provide any pivot table schema in your question) is the number one problem here.

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'products.wishlist_id' in 'where clause'

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'products.wishlist_id' in 'where clause' (SQL: select * from products where products.wishlist_id = 1 and products.wishlist_id is not null and products.deleted_at is null)
In my controller >>>
public function index() {
$wishlist_items = Wishlist::where('user_id', Auth::user()->id)->get();
foreach($wishlist_items as $item) {
dd($item->getProducts()->get());
}
}
Wishlist.php >>>
public function getProducts() {
return $this->hasMany(Product::class);
}
Product.php >>>
public function getWishlist() {
return $this->belongsTo(Wishlist::class);
}
Migration table >>>
Schema::create('wishlists', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('product_id');
$table->unsignedBigInteger('user_id');
$table->timestamps();
$table->foreign('product_id')->references('id')->on('products');
$table->foreign('user_id')->references('id')->on('users');
});
The hasMany() function queries the table for a {model_name}_id column - In this case, wishlist_id. Your products table is missing a wishlist_id column and the relevant foreign key. I'd suggest taking a look at the Laravel Documentation on one-to-many relationships.
Your migration will need to include updates to the existing products table to add the column and foreign key:
Schema::table('products', function (Blueprint $table) {
$table->unsignedBigInteger('wishlist_id');
$table->foreign('wishlist_id')->references('id')->on('wishlists');
});
That said, are you sure you're looking for a one-to-many relationship here? A wishlist can have multiple products, and a product can be in multiple wishlists - A many-to-many relationship may be a better option.

Change Primary ID in laravel Migration

I'm creating a table where I want to use the ID from this table "menu_items" to be added in another table
Table one: menu_items
Schema::create('menu_items', function (Blueprint $table) {
$table->id('menu_level_item_id');
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
Table 2 products
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->integer('menu_level_item_id');
$table->timestamps();
});
My aim of doing this is that I can then create a relationship between the 2 tables as they have the same key?
Is there a different approach I can take? Should I create a unique key when creating a menu item and then add this to the second table?
Thank you.
Basically Laravel Eloquent do the key handling. When you have two tables which both has as key the name id, this is not a problem. Name the keys in the relation table just like this
table1_id
table2_id
Laravel will handle this in Eloquent. You are also able to name the two columns in the relation table to what ever you want. You could define it for the relation in Eloquent. E.g.
public function otherModel () {
return $this->belongsToMany('App\Models\OtherModel', 'table_name', 'this_model_id', 'other_model_id');
}
Please have a look into:
Laravel Relationship Documentation
Schema::create('menu_items', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
table->timestamp();
});
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->unsignedBigInteger('menu_level_item_id');
$table->timestamps();
$table->foreign('menu_level_item_id')->references('id')->on('menu_items');
});

How to do join in different names in Laravel?

I have two tables named users and buys:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('first_name');
$table->string('last_name');
$table->string('referral_code')->nullable();
$table->integer('parent_id')->unsigned()->nullable();
$table->string('mobile')->unique();
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function up()
{
Schema::create('buys', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->bigInteger('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->timestamps();
});
}
I want to do a join on users.parent_id and buys.user_id. Here is my current query:
public function user ()
{
return $this->hasOne(User::class);
}
My query:
$users = Buy::all()->where('parent_id', auth()->user()->id)->latest()->paginate(25);
But my query throws this:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'parent_id' in 'where clause' (SQL: select count(*) as aggregate from buys where parent_id = 2)
Any idea how can I fix it?
When making the relationship, Laravel expects that the foreign key name will be the method name + _id in your case user_id which is okay for the local key, but the foreign key is not the id on the user table, so you need to tell Laravel that. So try this instead:
public function user ()
{
return $this->hasOne(User::class, 'parent_id', 'user_id');
}
-- EDIT after seeing your query
You are trying to use a column that does not exist on your buys model.
$users = Buy::with('user')->where('user_id', auth()->user()->id)->latest()->paginate(25);
It should be like
$users = Buy::where('user_id', auth()->user()->parent_id)->latest()->paginate(25);

Categories