Querying a value from two related table in laravel - laravel

I have related tables events and tickets which are related
class Event {
public function tickets(){
return $this->hasMany(Ticket::class);
}
}
class Ticket {
public function events(){
return $this->belongsTo(Event::class);
}
}
I have a store function getting data from and route URL
$ticket=new Ticket;
$ticket->userName= $request->input('userName');
$ticket->userEmail= $request->input('userEmail');
$ticket->phoneNumber= $request->input('phoneNumber');
$ticket->regular_quantity= $request->input('regular_quantity');
$ticket->vip_quantity= $request->input('vip_quantity');
$ticket->event_id=$request->route('id');
I have a variable max_attendees which I want to query the maximum attendees which is a column in events table where event id is
$ticket->event_id=$request->route('id');
query
$maximum_attendants=\App\Models\Event::with('Max_attendies')->where('id','=='$event_id');
events table
I have tried this but giving me syntax error, unexpected 'event_id' (T_STRING), expecting ')'

You're missing the , in your where clause:
where('id','==', $event_id)

If you are counting attendance from your 'tickets' table, you can use relation to count,
$event = Event::find($id);
$event->tickets()->count();

Related

select data no repeat in pivot table

I have 2 table and 1 pivot table which I use as table Historical, the column 'dateChange' indicated the store where is the employee, because I use Orderby ('dateChange','DESC'). All is ok, however how can I FILTER the results in my controller? without REPEAT records?.
I need to show all the employees that belong to a unique store. I repeat again: I use 'dateChange' for I know the last store. help me, please. Thanks
Pivot Table (employee_store)
FK_idStore
FK_idEmployee
dateChange
Table Employee
idEmployee
Name
Table Store
idStore
nameStore
direction
Model
public function employee(){
return $this->belongsToMany(employee::class,'employee_store', 'fk_idStore','fk_idEmployee')
->withPivot('dateChange')->orderBy('dateChange','DESC');
Controller
$store= Store::findOrFail($id)->employee
return $store
You have to change
public function employee(){
return $this->belongsToMany(employee::class,..
to
public function employees(){
return $this->belongsToMany(Employee::class,..
you should use eager loading:
in your Controller
$store= Store::findOrFail($id)->with('employee')->get();
return $store;
more details in:
https://laravel.com/docs/7.x/eloquent-relationships#eager-loading
To get the last record of each employee in each store, use:
public function employee(){
return Employe_Store::all()->groupBy('fk_idEmployee')->max('dateChange');
}

Laravel whereHas ManyToMany relation but then order by a value in the third table

I have 3 tables
entry (
id,
title,
other_stuff)
entry_award (
id,
award_id,
entry_id)
award (
id,
name,
type)
I am trying to create a laravel query which lets me get all the entries that have awards, and order them by award.type ASC
$Entries = Entry::with('award')
->whereHas('award', function ($query) {
$query->orderBy('award.award_id','ASC');
})->paginate(20);
But this doesn't work.
This is the sql version of it
SELECT DISTINCT entry.*
FROM entry, award, entry_award
WHERE entry.id = entry_award.entry_id
AND award.id = entry_award.award_id
ORDER BY award.type ASC;
Now I tried to just use the raw sql for it, but the problem seems to be that laravel does not then recognize the result as Entry models/objects. And i need to get other Entry relations later on in the html via blade.
So how can I either make a query-builder query that gets me all entries that have awards and orders them by award.type value
or use the raw sql but have Laravel see it as an array of Entry
objects instead of just an array of JSON values.
class Entry extends Model {
public function entry_award(){
return $this->belongsToMany('App\Award', 'entry_award');
}
}
class Award extends Model {
public function entries() {
return $this->belongsToMany('App\Entry', 'entry_award');
}
}

Laravel returns a Collection with duplicates of the first model

I'm developing a Laravel 5.7 (API) application with a PostgreSQL database behind it. The relevant Models are: User (customers and employees), Car, and Request.
An employee User creates a Request for a Car, that belongs to a customer User.
The relationships are:
Car (as customer) : User = n:m
Car : Request = 1:n
User : Request (as employee) = 1:n
(The data design is suboptimal, to put it mildly, but anyway, it's the given reality for now.)
Now to the actual issue. I want to display all Requests of a customer User:
Request::query()
->join('user_car', 'user_car.car_id', '=', 'request.car_id')
->join('user', 'user.id', '=', 'user_car.user_id')
->where('user.id', '=', $customer->id)
->select()
->get();
The customer with the given $customer->id has n Requests. And the length of the result Collection of the call above is correct. But all these n entries are duplicates of the first one. Means: I'm getting a list with n instances of Request#1.
Why does the first call return a list of references to the same Model object? Is it a (known) bug?
ADDITIONAL INFORMATION
Relationships:
class User extends \Illuminate\Foundation\Auth\User
{
// ...
public function cars()
{
return $this->belongsToMany('App\Car', 'user_car')->withTimestamps();
}
public function requests()
{
return $this->hasMany(Request::class, 'user_id');
}
}
class Car extends Model
{
// ...
public function users()
{
return $this->belongsToMany('App\User', 'user_car')->withTimestamps();
}
public function requests()
{
return $this->hasMany(Request::class);
}
}
class Request extends Model
{
// ...
public function car()
{
return $this->belongsTo(Car::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
The query is correct.
I logged the database requests, got the generated statement
SELECT *
FROM "request"
INNER JOIN "user_car" ON "user_car"."car_id" = "request"."car_id"
INNER JOIN "user" ON "user"."id" = "user_car"."user_id"
WHERE "user"."id" = 1;
..., and executed it manually. The result table contains as expected n different entries.
NOT just references
The result Collection's entries instances references to the different objects:
$test1 = $resultCollection->first();
$test2 = $resultCollection->last();
$test3 = spl_object_hash($test1);
$test4 = spl_object_hash($test2);
Xdebug output:
$test3 = "0000000077505ccd000000007964e0a8" <-- ccd0
$test4 = "0000000077505c33000000007964e0a8" <-- c330
Workaround
I found a workaround. This call
Request::whereIn('car_id', $customer->cars()->pluck('id')->toArray())->get();
... retrieves the correct/expected set of model.
First, note that your object hashes are not actually identical, and you're likely dealing with two separate instances.
What you're likely experiencing is an issue with ambiguous column names. When you JOIN together multiple tables, any matching/duplicate column names will contain the value of the last matching column. Your SQL GUI/client usually separates these. Unfortunately Laravel doesn't have a prefixing mechanism, and just uses an associative array.
Assuming all of your tables have a primary key column of id, every Request object in your result set will likely have the same ID - the User's ID you pass in the WHERE condition.
You can fix this in your existing query by explicitly selecting the columns you need to prevent ambiguity. Use ->select(['request.*']) to limit the returned info to the Request object data.

Selecting specific column in ORM relationship Laravel 5.5

I have an order table with a primary key id and another table trips. I trip can have many orders. I have defined the relationship in this way
public function orders_currency() {
return $this->hasMany('App\Order', 'trip_id', 'id')->select('id', 'converted_currency_code');
}
Although I know that, I have to select id of the order table in order to get the result, that's why I am mentioning to select the id of the order table.
Despite this, I am getting the orders_currency index empty. Which angle am I missing in this case?
Any clue will be appreciated.
Did you set up the model correctly?
You'd do something like this in your model script I suppose
class Trips extends Model
{
public function orders() {
return $this->hasMany('Order');
}
I got the solution by doing this way
public function orders_currency() {
return $this->hasOne('App\Order', 'trip_id', 'id')
->select('trip_id','converted_currency_code');
}
I had to select referencing key in this case.

"column isn't in GROUP BY" when using "belongsToMany"

I need to check if ManyToMany relationship exists. I have a business that can have many members and members that can have many businesses.
I have pivot table: business_member. I am trying to use the code I found in this post, but I'm getting an error on Laravel.
When I try to run the mysql query from an editor, I get no errors and an empty results.
In my Business model:
public function membersCount()
{
return $this->belongsToMany('App\Member')->selectRaw('count(members.member_id) as aggregate')->groupBy('pivot_business_id');
}
public function getMembersCount()
{
if ( ! array_key_exists('membersCount', $this->relations)) $this->load('membersCount');
$related = $this->getRelation('membersCount')->first();
return ($related) ? $related->aggregate : 0;
}
In my controller:
$business = Business::findOrFail($id);
dd($business->getMembersCount());
I get this error:
SQLSTATE[42000]:
Syntax error or access violation:
1055 'ccf.business_member.member_id' isn't in GROUP BY
(SQL: select count(members.member_id) as aggregate, `business_member`.`business_id` as `pivot_business_id`, `business_member`.`member_id` as `pivot_member_id` from `members` inner join `business_member` on `members`.`member_id` = `business_member`.`member_id` where `business_member`.`business_id` in (2) group by `pivot_business_id`)
It is much easier than that. First you need to define manyToMany relationship in your Business model like this:
/**
* The members that belong to the business.
*/
public function members()
{
return $this->belongsToMany('App\Members');
}
If you want to check how many members a given business has you can do it like this for example:
$business = Business::findOrFail($id);
dd($business->members()->count());

Resources