Eloquent Models with hasMany WHERE condition - php

I'm fairly new to Laravel 5.5 and Eloquent, so I'm struggling to work out how to do this using Eloquent objects.
If I was going to do this in SQL it would be pretty simple, but I'd prefer to deal in Eloquent objects.
I have two tables, Lots and Bids and I have the models that go with these.
Is there a way to get any Lot model where a specific user has bid on it (user_id column in the bids table), and then get the maximum bid amount that the user has bid?

Thanks to Devon, I used the whereHas to return the models that I needed. I then added another method to the model that returned the max bid price.

Related

Delete/update laravel pivot table entry by id

I've got a database structure as follows where item A is in a many to many relationship with B.
This is a true many to many, so:
Item X (object in table A) relates to Y (object in B) multiple times.
Using the laravel attach() function easily adds these records. However, I need to update and delete these items.
The detach() and sync() methods seem to not be appropriate. They assume only one pivot table entry between one record and another record.
If I detach() then ALL items are deleted. That is not what I want.
So the main point of my question:
If I have the id of the pivot table record, how do I delete/update it... given that detach doesn't work as expected.
Or put another way:
How can I interact with a pivot table object directly?
You can use newPivotQuery().
Something like that:
Parent::relation()->newPivotQuery()->where('id', $someId)->delete();
The where() and delete() statements will apply to the pivot query.
Thanks to all,
#devk has pointed out a good solution to the problem if you have the child objects available. I've upvoted this answer because it is true and useful for future reference.
Unfortunately, at this particular point I only have the many-to-many id, so i am answering this with a "No - there is no specific way to access the pivot table by id" using the Pivot or similar objects.
However: to be clear, this can still be done in eloquent using the DB class.
DB::table('many-to-many-lookup')
->where('id', $id)
->take(1)
->delete();

laravel Eloquent join and Object-relationship mapping

Ok so i'm kind of newish to eloquent and laravel (not frameworks tho) but i hit a wall here.
I need to perform some queries with conditions on different tables, so the eager load (::with()) is useless as it creates multiples queries.
Fine, let use the join. But in that case, it seems that Laravel/Eloquent just drops the concept of Object-relationship and just return a flat row.
By exemple:
if i set something like
$allInvoicesQuery = Invoice::join('contacts', 'contacts.id', '=', 'invoices.contact_id')->get();
and then looping such as
foreach ($allInvoicesQuery as $oneInvoice) {
... working with fields
}
There is no more concept of $oneInvoice->invoiceFieldName and $oneInvoice->contact->contactFieldName
I have to get the contacts fields directly by $oneInvoice->contactFieldName
On top of that the same named columns will be overwrited (such as id or created_at).
So my questions are:
Am i right assuming there is no solution to this and i must define manually the field in a select to avoid the same name overwritting like
Invoice::select('invoices.created_at as invoice.create, contacts.created_at as contact_create)
In case of multiple joins, it makes the all query building process long and complex. But mainly, it just ruins all the Model relationship work that a framework should brings no?
Is there any more Model relationship oriented solution to work with laravel or within the Eloquent ORM?
Instead of performing this join, you can use Eloquent's relationships in order to achieve this.
In your Invoice model it would be:
public function contact(){
return $this->belongsTo('\App\Contact');
}
And then of course inside of your Contact model:
public function invoices(){
return $this->hasMany('\App\Invoice');
}
If you want to make sure all queries always have these active, then you'd want the following in your models:
protected $with = ['Invoice']
protected $with = ['Contact'];
Finally, with our relationships well defined, we can do the following:
$invoices = Invoice::all();
And then you can do:
foreach($invoices as $invoice)[
$invoice->contact->name;
$invoice->contact->phone;
//etc
}
Which is what I believe you are looking for.
Furthermore, you can find all this and much more in The Eloquent ORM Guide on Laravel's site.
Maybe a bit old, but I've been in the same situation before.
At least in Laravel 5.2 (and up, presumably), the Eloquent relationships that you have defined should still exist. The objects that are returned should be Invoice objects in your case, you could check by dd($allInvoiceQuery); and see what the objects are in the collection. If they are Invoice objects (and you haven't done ->toArray() or something), you can treat them as such.
To force only having the properties in those objects that are related to the Invoice object you can select them with a wildcard: $allInvoicesQuery = Invoice::select('invoices.*')->join('contacts', 'contacts.id', '=', 'invoices.contact_id')->get();, assuming your corresponding table is called invoices.
Hope this helps.

Retrieve nested relationships for a model instance in Laravel's Eloquent

My scenario is this:
I have a Course model
Each Course can have many CourseTopics, through a topics() relationship
Each CourseTopic can have many Lessons, through a lessons() relationship
Is there a compact way to retrieve and handle all the Lessons associated with a single Course (for example, to list them, or to count their total number)?
My aim would be to have a very brief syntax to use in Blade templates; I don't want to involve logic (or at least, keep it to a bare minimum) or raw SQL queries into my template.
What I've tried:
$course->with("topics.lessons")
where $course is the current instance of the course in a template, doesn't work (gives to me all the courses with all their topics and lessons).
EDIT:
A solution is to define a hasManyThrough() relationship like:
$this->hasManyThrough("Lessons", "CourseTopics");
This solves the problem for a 2-level nested relationship. How about a 3-level instead?

Laravel 4 One to One relationship

I would like to have a one to one relationship with a pivot table or by referencing an ID in a table.
I currently have a Films table that has a one to many relationship with a Stock table, each stock item needs a format, however I would like the formats to be a set list of formats so I created a Formats table that only has 2 columns ID and Name
Normally I would just add a Format_ID column to the Stock table however I'm unsure how this would work with the Eloquent ORM or if it's even possible / best practice
Sorry if this is hard to understand, cant quite figure out the best way of explaining it
The structure you desire is pretty standard practice. It's quite possible!
Which Eloquent relationship you'd use depends on the direction of the relationship. Each Stock has one Format (one-to-one). But each Format can be assigned to multiple Stock (one-to-many).
For the former, your Stock Eloquent model would have a hasOne() one-to-one relationship.
class Stock extends Eloquent {
public function format()
{
return $this->hasOne('Format');
}
}
For the latter, your Format eloquent model would have a hasMany() one-to-many relationship.
class Format extends Eloquent {
public function stock()
{
return $this->hasMany('Stock');
}
}
Note that having both of these defined is totally acceptable and normal. It really just depends on which direction you need your relationship to go. If you never need to look up what Stock belongs to a specific Format, you don't need the one-to-many relationship.
Also note that you may need to add a column key parameter if your column names are not easily guessable by Eloquent. E.g.:
return $this->hasOne('Format', 'my_format_id');

Difference between HABTM relationship and 2 $belongsTo relationship with a third model

I'm creating a project management system which projects are assigned to users
What's the difference between creating a Model ProjectsUser and defining 2 $belongsTo relationship and defining HABTM relationships in both Project and User models? What would be the most correct way, though? And how do I save the data in the projects_users table?
From my experience, if you want to be able to save or delete rows only from the join table (the one with 2 IDs), then it is much more simple using three models associated through both a hasMany and a belongsTo association.
You can also retrieve data from the join table directly and do the queries you want much more easily
This is what CakePHP documentation says refering to HABTM and saving data:
However, in most cases it’s easier to make a model for the join table and setup hasMany, belongsTo associations as shown in example above instead of using HABTM association.
Here you can find more the full text:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I have used this method for a "reads" table (with post_id and user_id) as well as for subscriptions and similar kind of relationships.
The first way is called "hasAndBelongsToMany" [details here].
The second is called "hasMany through" [details here].
The second link relating to "hasMany through" has details and a lengthy explanation about when and why you would want to use it.
Not sure about the specifics of cakephp, but in general defining the relation model explicitly gives you more control over it, for instance if you wanted to do some validation or add callbacks on creation of this relationship.

Categories