How to do join in different names in Laravel? - php

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);

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.

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');
});

Select statement with group_concat not working when other columns are called in laravel

Hello my laravel code is
$productDetails = DB::table('products')
->select(DB::raw('products.name, GROUP_CONCAT(sizes.name) as sizesName'))
->join('subcategories', 'products.subcategories_id', '=', 'subcategories.id')
->join('size_categories', 'subcategories.categories_id', '=', 'size_categories.categories_id')
->join('sizes',function($join){
$join->on(DB::raw("FIND_IN_SET(sizes.id, size_categories.size_id)"),">",DB::raw("'0'"));
})
->where('products.id', $request->id)
->get();
This doesnt work, when i useproducts.name or any other column name in select statement
but when i use only group_concat inside Db::raw and nothing else, the query works.
So how do i fetch other columns?
Please help.
I am stuck on it for quite a while
The query i want is
select GROUP_CONCAT(sizes.name),`products`.`name`, `products`.`image`, `products`.`id`, `products`.`image_second`, `products`.`description`, `products`.`min_order`, `size_categories`.`size_id` from `products`
inner join `subcategories` on `products`.`subcategories_id` = `subcategories`.`id`
inner join `size_categories` on `subcategories`.`categories_id` = `size_categories`.`categories_id`
join sizes on (FIND_IN_SET(sizes.id,size_categories.size_id)>0) where `products`.`id` = '7'
Please note that the above query is working fine. I just cant make it in laravel to work. Only the group_concat part.
This is the screenshot from my database, when i dont use group_concat
Also the DISTINCT part is doing nothing there, please ignore it.
I was just trying that out
This is the migration of create_products_table
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('units_id');
$table->unsignedBigInteger('selections_id');
$table->unsignedBigInteger('subcategories_id');
$table->string('name');
$table->string('image');
$table->text('description');
$table->string('min_order');
$table->timestamps();
$table->index('units_id');
$table->index('selections_id');
$table->index('subcategories_id');
});
}
migration of create_subcategories_table
public function up()
{
Schema::create('subcategories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedBigInteger('categories_id');
$table->timestamps();
$table->index('categories_id');
});
}
data of size_categories table
public function up()
{
Schema::create('size_categories', function (Blueprint $table) {
$table->id();
$table->string('size_id');
$table->unsignedBigInteger('categories_id');
$table->timestamps();
$table->index('categories_id');
});
}
migration of categories table
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
migration of sizes table
public function up()
{
Schema::create('sizes', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
In sizes table data is in this form
id name
1 2m
2 3m
3 4m
First, you need to specify select columns separately. Like so:
->select(DB::raw('products.name'), DB::raw('GROUP_CONCAT(sizes.name) as sizesName'))
Next, since group concat is an aggregate column, you need to group the sizes, and product name since it's in the select list and it is not related to size.
->groupBy('size_categories.size_id', 'products.id') //edit after your comment. group by prodcuts.id to be able to select columns from products table.
So your final query should look like this:
$productDetails = DB::table('products')
->select(DB::raw('products.name'), DB::raw('GROUP_CONCAT(sizes.name) as sizesName'))
->join('subcategories', 'products.subcategories_id', '=', 'subcategories.id')
->join('size_categories', 'subcategories.categories_id', '=', 'size_categories.categories_id')
->join('sizes',function($join){
$join->on(DB::raw("FIND_IN_SET(sizes.id, size_categories.size_id)"),">",DB::raw("'0'"));
})
->where('products.id', 7)
->groupBy('size_categories.size_id', 'products.id')
->get();

Laravel table referencing itself through pivot

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.

Categories