relations with 4 tables in laravel - php

I have four tables as follows.
Services_cats
Session_pat
Invoice_item
Invoice
id
id
id
id
name
services_cat_id
service_id
code
patient_id
invoice_id
discount
I need to have relations among them with one Eloquent query in Laravel. Below is what I have reached so far; I used many-to-many relations in the invoice table.
public function invoice_item()
{
return $this->belongsToMany(Session_pat::class, 'invoice_items', "invoice_id",
"service_id", "id", "id");
}
And I used this code to access the four tables.
$status4 = Invoice::select('id')->with(['invoice_item' => function ($q){
$q->select('id', 'services_cat_id')
->with(['service_cat' => function ($q) {$q->select('id as myid', 'name');}])
;}])
->where('id', 122)->get();
but I get this error
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in
field list is ambiguous (SQL: select id, services_cat_id,
invoice_items.invoice_id as pivot_invoice_id,
invoice_items.service_id as pivot_service_id from session_pats
inner join invoice_items on session_pats.id =
invoice_items.service_id where invoice_items.invoice_id in
(122) order by id desc)

You Should Specific The Table Name, WHen Using Same Column Name In Query.
Rule: tableName.column EX: invoiceTable.id
$status4 = Invoice::select('TableName.id')->with(['invoice_item' => function ($q){
$q->select('TableName.id', 'services_cat_id')
->with(['service_cat' => function ($q) {$q->select('TableName.id as myid', 'name');}])
;}])
->where('TableName.id', 122)->get();

Related

how to query whereHas on a belongs to many relationship using laravel

hi i am having a User and Task model and they have a many to many relation ship like below i added :
public function users()
{
return $this->belongsToMany(User::class,'user_tasks');
}
and in my user model :
public function tasks()
{
return $this->hasMany(Task::class);
}
and in my controller i want to get the task that are assigned to the logged in user like below :
$task = Task::whereHas('users', function(Builder $query){
$query->where('id',Auth::user()->id);
})->get();
dd($task);
but i get this error :
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous (SQL: select * from `tasks` where exists (select * from `users` inner join `user_tasks` on `users`.`id` = `user_tasks`.`user_id` where `tasks`.`id` = `user_tasks`.`task_id` and `id` = 4))
and when i change the id to users.id i get empty value but when i load it like below :
$task = Task::with('users')->get();
i get all the task with the relationships and they are working well but with whereHas its not working
thanks in advance
Since you are dealing with the pivot table with this relationship you can use the pivot table field user_id to filter:
$task = Task::whereHas('users', function (Builder $query) {
$query->where('user_id', Auth::user()->id);
})->get();
why not just:
$userTasks=Auth::user()->tasks;
this will get the current user tasks.

Can't convert SQL query to laravel eloquent

I have this query that will get how many user votes with each star number
SELECT stars, COUNT(*) AS rate FROM product_user where product_id = 1 GROUP BY(stars)
result of this query
stars | rate
_____________
2 | 3
5 | 4
but I can't convert it to laravel eloquent
this is my try but it gets an error
Product::find($id)->votes()->selectRaw('count(*) as rate, stars')
->groupBy('stars')
->get();
Error message
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'roya.users.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: select `users`.`id`, `first_name`, `last_name`, count(*) as rate, stars, `product_user`.`product_id` as `pivot_product_id`, `product_user`.`user_id` as `pivot_user_id`, `product_user`.`stars` as `pivot_stars`, `product_user`.`feedback` as `pivot_feedback`, `product_user`.`created_at` as `pivot_created_at`, `product_user`.`updated_at` as `pivot_updated_at` from `users` inner join `product_user` on `users`.`id` = `product_user`.`user_id` where `product_user`.`product_id` = 1 group by `stars`)
Product Model
class Product extends Model {
public function votes()
{
return $this->belongsToMany(User::class)
->using('App\Review')
->select('users.id', 'first_name', 'last_name')
->withPivot(['stars', 'feedback'])
->withTimeStamps();
}
}
When you use grouped select queries SQL allows only for aggregated functions or columns specifically listed in GROUP BY section to be selected. Your votes() relationship adds extra select columns to your query ('users.id', 'first_name' and 'last_name') and they are causing an error. This happens because selectRaw method doesn't replace previously selected columns, but utilizes addSelect() method to add raw on top of the existing ones.
In your case it's really cumbersome to use Eloquent here when you only need an aggregated count data for specific product votes.
Just add getVotesCountByStars method to your Product model and utilize Laravel's generic query builder via DB facade:
public function getVotesCountByStars()
{
return DB::table('product_user')
->where('product_id', $this->id)
->selectRaw('count(*) as rate, stars')
->groupBy('stars')
->orderBy('stars', 'asc')
->get()
->pluck('rate', 'stars')
->toArray();
}
This way you will see exactly what query is generated and no additional overhead is produced (in my example, an associative array with stars as keys and counts as values will be returned).
What you could do is is add a ratings relationship to your Product model that is a hasMany between Product and Rating:
public function ratings()
{
return $this->hasMany(Rating::class)
->select('stars', 'product_id')
->selectRaw('count(*) as rate')
->groupBy('stars', 'product_id');
}
Then your query would be something like:
$product = Product::with('rating')->find(1);
This would product something like:
{
"id":1,
...
"ratings":[
{
"stars":2,
"product_id":1,
"rate":1
},
{
"stars":3,
"product_id":1,
"rate":2
},
{
"stars":4,
"product_id":1,
"rate":4
},
{
"stars":5,
"product_id":1,
"rate":3
}
]
}

Integrity constraint violation: 1052 Column 'prof_id' in where clause is ambiguous Laravel

What I'm trying to do is very simple, Running a query with some relations and giving that relation a where clause.the query suppose to get questions with the related relations BUT the where clause on tags tells only get questions with the tag that been sent ($value).
userQuestion Model :
<?php
namespace App;
class userQuestion extends Model
{
protected $table = "question";
public $primaryKey = "question_id";
protected $fillable = ['question_id'];
public function gettags() {
return $this->belongsToMany('App\Profskills','question_profskill',"question_id","prof_id");
}
}
Query
$allquestions = userQuestion::with('getanswer','getusername','getbounty','gettags')
->whereHas('gettags', function($q) use($value) {
$q->where('prof_id', '=', $value);
})
->orderBy('created_at','Desc')
->get();
the problem is it gives me this error
QueryException in Connection.php line 729:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'prof_id' in
where clause is ambiguous (SQL: select * from `question` where exists
(select * from `prof_skills` inner join `question_profskill` on
`prof_skills`.`prof_id` = `question_profskill`.`prof_id` where `question_profskill`.`question_id` = `question`.`question_id` and
`prof_id` = 1) order by `created_at` desc)
the column exist and if i switch the column to qp_id(PrimaryKey) it will work and the Columns are from the pivot table that im trying to access
Did some googling, what i did was :
1-put fillable with 'prof_id' in the model ( since i have a model for the pivot table too , did the same thing)
2-try =>where instead of whereHas
Still stuck,
Thanks for any help!
Add table name with your field as you have prof_id in both tables.
$allquestions = userQuestion::with('getanswer','getusername','getbounty','gettags')
->whereHas('gettags', function($q) use($value) {
$q->where('question_profskill.prof_id', '=', $value); //question_profskill or prof_skills
})
->orderBy('created_at','Desc')->get();

Join three tables and orderBy in laravel getting an error

I'm trying to use join() in laravel5.1 but I'm getting this error:
QueryException in Connection.php line 666: SQLSTATE[23000]: Integrity
constraint violation: 1052 Column 'id' in where clause is ambiguous
(SQL: select * from quizzes inner join question_numbers on
question_numbers.quiz_id = quizzes.id and
question_numbers.question_id = multiple_choice.id inner join
multiple_choice on multiple_choice.id =
question_numbers.question_id where id = 1)
I have three tables here and I want to join these three tables. What I want first is to get a quiz where id = to a specific id then join the table question_numbers where question_numbers.quiz_id is = to the quiz.id then join the table multiple_choice where multiple_choice.id is = question_numbers.question_id and where question_numbers.question_type = multiple_choice.
What I have:
$quiz = DB::table('quizzes')->where('id', $id)
->join('question_numbers', function($join){
$join->on('question_numbers.quiz_id', '=', 'quizzes.id')
->on('question_numbers.question_id', '=', 'multiple_choice.id');
})
->join('multiple_choice', 'multiple_choice.id', '=', 'question_numbers.question_id')
->get();
dd($quiz);
First, you need to set a table aliaslike this quizzes as t for your table that belongs the where condition's id (I assume you meant quizzes table id column here) and then if you refer it inside where like where('t.id', $id), it will not complain about the ambiguous integrity because other table also have id column that's why it is showing you the below Query exception,
Column 'id' in where clause is ambiguous
Try like this,
$quiz = DB::table('quizzes as t')->where('t.id', $id)
->join('question_numbers', function($join){
$join->on('question_numbers.quiz_id', '=', 't.id');
})
->join('multiple_choice', 'multiple_choice.id', '=', 'question_numbers.question_id')
->get();
dd($quiz);

query builder using 'whereNotIn' throws error

I'm trying to fetch records with an array of exceptions, here's what I tried (refer below)
$users_nowishlist = DB::table('employee')
->join('users', 'users.employee_id', '=', 'employee.employee_id')
->where('has_wishlist', '=', "0")
->whereNotIn('employee_id', ['MMMFLB003', 'guest_01', 'guest_02', 'guest_03'])
->where('employment_status', '=', 'ACTIVE')
->get();
so in this line was my records filter, means only records that does not equal to any of those 'employee_id' from the exceptions array will be return (refer below)
->whereNotIn('employee_id', ['MMMFLB003', 'guest_01', 'guest_02', 'guest_03'])
but instead I got this error (refer below):
SQLSTATE[23000]: Integrity constraint violation: 1052 Column
'employee_id' in where clause is ambiguous (SQL: select * from
employee inner join users on users.employee_id =
employee.employee_id where has_wishlist = 0 and employee_id
not in (MMMFLB003, guest_01, guest_02, guest_03) and
employment_status = ACTIVE)
any ideas, help please?
This happens because when you are doing the join there are two columns with the same name.
That's why on your join you prefix the employee_id with users. and employee.
Now on your whereNotIn you also have to prefix it, so the query engine knows which table column you are trying to reference. So you only have to add the prefix in your whereNotIn clause:
->whereNotIn('employee.employee_id', ['MMMFLB003', 'guest_01', 'guest_02', 'guest_03'])
->whereNotIn('employee.employee_id', ['MMMFLB003', 'guest_01', 'guest_02'])
when using join , these errors are expected if you have two fields have the same name in the tables you join between, so always try to fetch them like this
table_name.field_name

Categories