Laravel Eloquent ManyToMany getLatest - mysql

I built up a pivot table containing ids of tables I want to associate. When I have the id of a specific item, I now want to get the latest entry of this item saved in the pivot table. For example:
Table 1: Tickets
Table 2: Status
Table 3: Ticket_Status (Pivot)
If I add a new entry to the pivot table, I would have something like this:
Pivot
ticketId, statusId
1, 2
1, 3
2, 1
Now I want to receive the latest status in the pivot for Ticket Id 1 for example, so I expect to receive statusId 3 for ticket 1. But how do I do this in Laravel?
Creating the entries for the pivot table works:
public function attachDispatchStatus($id) {
$this->status()->attach($id);
$this->touch();
}
// set fields on the eloquent object and save to database
// raise event that the incident was created.
public function createDispatch($command) {
// Get BodyContent from POST Request
$this->dispatchReference = $command->dispatchReference;
$this->incidentReference = $command->incidentReference;
// Create new Dispatch
$dispatch = Dispatch::create(array(
'dispatch_reference' => $this->dispatchReference,
'incident_reference' => $this->incidentReference
));
$dispatchStatus = DispatchStatus::where('status', '=', 'processing')->first();
$dispatch->attachDispatchStatus($dispatchStatus->id);
return $this;
}

Why don't you use the updateExistingPivot($roleId, $attributes); available in Laravel 5 when editing your tickets ?
This will solve your problem and make your database lighter :)
Check Larvel Doc for some examples on pivot table.
If you don't want to make it like that (because you want to keep an historic of your input), I think you will have to add an dateTime field in your pivot table... Then, just order by date, and you will be fine.

Related

Filter Table, based on field in another table

I'm stumped with this. I have a table with various fields:
$employees. This, I guess, is what you call a collection, I think, that when I call, returns all employee records in the database (4 records in this example)
Each employee record has the following fields
first_name, last_name, age, other_id
There is another table (or collection), which I'm calling filter table. It is called $other_ids. This has two records, with the following fields - id, id_name.
I want to be able to filter the $employees table so that it only keeps the records, where other_id is equal to one of the two values of id in the filter table- $other_ids
So for example, if the filter table has the following two records:
[{"id":1 "id_name":"one"}, {"id":2, "id_name":"two"}]
And the $employee table contains the records:
[{"first_name":"ted", "surname_name":"stark", "age":35, "other_id":1},
{"first_name":"fred", "surname_name":"strange", "age":30, "other_id":2},
{"first_name":"incredible", "surname_name":"hulk", "age":25, "other_id":3},
{"first_name":"captain", "surname_name":"stone", "age":28, "other_id":2}]
After, the filtering, it should return $employees_filtered should only have records 1, 2, and 4
I've tried doing left-join and using whereHas, and where clauses, but nothing works!
I think you are looking for something like -
$otherId = [1, 2];
$employees_filtered = Employee::with('Others')->whereIn('other_id', $otherId)->get();
Please don't forget to make a relationship with their model.
In Other.php model -
public function Employees()
{
return $this->hasMany('App\Other', 'other_id', 'id');
}
And in Employee.php model -
public function Others()
{
return $this->belongsTo('App\Employee', 'other_id', 'id');
}

Two unique values in column Laravel 5.3

I'm making a reservation system for a media library, the goal is to book a room for a certain time. There are 8 time slots in total with a start_time & end_time.
The user has to fill in a date and I have to check what time slots are still available at that date.
So, for example.. there can only be one row in the database that contains date: 2016-12-08 time_slot: 3.
How do I check if this row exists in my database using Eloquent?
You can do laravel model query to check if there is any results, like this :
$data = Model::where('date','2016-12-08 ')->where('time_slot', 3)->count();
Assuming you have a slot table with the fields you are sharing. Slot table: id, date, time_slot...
$your_date = 2016-12-08;
$date = date('Y-m-d', strtotime($your_date));
$time_slot: 3;
$slot = Slot::where('date', $date)->where('slot', $time_slot)->first();
if($slot == null) {
// book can be made
}
else {
// already booked
}
You can take the help pf Laravel Query Builder's exists for checking the if the fields are present in database like this:
$exists = Model::whereDate('date', '2016-12-08')
->where('time_slot', 3)
->exists();
Here exists returns a boolean value, which depends upon the existence of the query above!
Hope this helps!

How to fetch records from two different tables in laravel5.2

I have two tables 'approval' and 'renewal', both having a common column 'applicant_id'.
When new application comes-in, it stores a data-record in table 'approval' alongwith the 'applicant_id' for whom the record has been added.
Now, when there is a renew applied for that same applicant, the row gets created in the table 'renewal' referencing the 'applicant_id'
Note: There can be a single record in the table 'approval' for a 'applicant_id' but there can be more than one record for the same 'applicant_id' in the table 'renewal'.
Now, my requirement is:
I need to fetch the records from both the table for all the applicants.
Conditions: If there is a data for the 'applicant_id' in both the table and 'renewal' table has multiple row for the same 'applicant_id', then I need to get the records from 'renewal' table only that too the latest one.
If there is no data in 'renewal' table but exists in 'approval' table for the 'applicant_id', then the fetch record should get the data present in 'approval' table.
Basically, if there is record for the applicant in 'renewal' table, get the latest one from there, if there is record present only in 'approval' table, then get that one but the preference should be to get from 'renewal' if exists.
I am trying to do this in laravel 5.2. So, is there anyone who can help me in this?
If you're using Eloquent, you'll have 2 models:
Renewal.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Renewal extends Model
{
protected $table = 'renewal';
public static function findMostRecentByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->orderBy('date_created', 'desc')
->first();
return $applicant;
}
}
Approval.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Approval extends Model
{
protected $table = 'approval';
public static function findByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->first();
return $applicant;
}
}
Then, in the code where you want to get the approval/renewal record, use the following code:
if (! $record = Renewal::findMostRecentByApplicantId($applicantId)) {
$record = Approval::findByApplicantId($applicantId);
}
//$record will now either contain a valid record (approval or renewal)
//or will be NULL if no record exists for the specified $applicantId
After few try, I got one way to do it using raw:
SELECT applicant_id, applicant_name, applicant_email, applicant_phone, renewed, updated_at
FROM (
SELECT renewal_informations.applicant_id, renewal_informations.applicant_name, renewal_informations.applicant_email, renewal_informations.applicant_phone, renewal_informations.renewed, renewal_informations.updated_at
FROM renewal_informations
UNION ALL
SELECT approval_informations.applicant_id, approval_informations.applicant_name, approval_informations.applicant_email, approval_informations.applicant_phone, approval_informations.renewed, approval_informations.updated_at
FROM approval_informations
) result
GROUP BY applicant_id
ORDER BY applicant_id ASC, updated_at DESC;
For every single Approval id, there can b multiple records for renewal table suggests you have One to Many relation. which you can define in the your Model like
Approval.php (App\Models\Approval)
public function renewal()
{
return $this->hasMany('App\Models\Renewal', 'applicant_id')
}
Having defined this relation. you can get the records from the table using applicant_id.
$renewal_request_records = Approval::find($applicant_id)->renewal();
This will get all records from renewal table against that applicant_id.
Finding the latest
$latest = Renewal::orderBy('desc', 'renewal_id')->first();
Further Readings Eloquent Relations

Display created_at from pivot table in Laravel 4

I have a three tables - attendees, messages and attendee_message. When a users is sent a standardized message a record is added to the pivot table attendee_message with the id of the attendee, the id of the message and a date/time stamp in the created_at field.
My issue is that both the attendees and messages tables have a field called created_at and when I go to display the date/time the message was sent (the created_at from the attendee_message column) it displays the created_at from the messages table. How do I display the created_at from the attendee_message table instead?
The function that gets the attendees, a scope and the relationship from the model:
public function getatts() {
$atts = Attendee::cmo()->orderBy('created_at');
$atts = $atts->paginate(25);
return $atts;
}
public function scopeCmo($query)
{
return $query->where('block_id', '=', 3);
}
public function messages() {
return $this->belongsToMany('\App\Models\Message','attendee_message','attendee_id','message_id')
->withPivot('id');
}
From my list.blade.php:
#foreach ($att->messages as $message)
<li>'{{$message->subject}}' sent {{$message->created_at}}</li>
#endforeach
To access the row in the pivot table you can use the pivot property. Laravel docs
$message->pivot->created_at
However, by default there are only keys present in the pivot object. So you will need to do
->withPivot('created_at');
on the relationship. In your case it would be ->withPivot('id', 'created_at') if you want to have id in there as well

Trouble counting rows with specific value - Doctrine, Symfony2, mysql

I'm working on querying my mysql database via doctrine in a symfony2 app. I have a basic table set up that includes an id number ('id'), name ('name'), and a last column for if the person has been contacted ('contacted'), depicted with 0 or 1. I can query and get the number of total inquiries (depicted in the controller with $inquiryCountTotal just fine.
I'm struggling to count the rows that have been contacted. I figure I can either COUNT the rows with a value of 1 in the contacted column or I could just SUM all the rows in the contacted column.
For some reason it seems to be summing the ids, as I have 8 ids and it's spitting a number of 36.
Where am I going wrong? Thanks in advance!
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('EABundle:Inquiry')
->findBy(array(), array('id'=>'DESC'));
$inquiryCountTotal = $em->createQuery("
SELECT count(id)
FROM EABundle:Inquiry id
")->getSingleScalarResult();
//This is the part I'm struggling with...
$inquiryCount = $em->createQuery("
SELECT sum(contacted)
FROM EABundle:Inquiry contacted
")->getSingleScalarResult();
return $this->render('EABundle:Inquiry:index.html.twig', array(
'entities' => $entities,
'inquiryCount' => $inquiryCount,
'inquiryCountTotal' => $inquiryCountTotal
));
}
Doctrine is interpreting the alias as the id of the entity.
Try this:
$inquiryCount = $em->createQuery("
SELECT sum(i.contacted)
FROM EABundle:Inquiry i
")->getSingleScalarResult();