Hey I have a problem with Laravel on my site Phones number lookup. I try to choose places that have city that I choose, through contact table.
My model classes: Places class:
class Places extends Eloquent {
public function contacts()
{
return $this->hasOne('Contacts');
}
public function clubs()
{
return $this->hasOne('Clubs');
}
}
Contacts class:
class Contacts extends Eloquent {
public function cities()
{
return $this->hasOne('Cities');
}
}
Cities class:
class Cities extends Eloquent {
}
My query:
$view->clubs = Places::whereHas('contacts',function ($q) use($city_id){
$q->where('contacts', function ($q) use($city_id){
$q->where('id', $city_id);
});
})->get();
Error msg:
MySQL server version for the right syntax to use near 'where
id
= ?)) >= 1' at line 1 (SQL: select * fromplaces
where (select count(*) fromcontacts
wherecontacts
.places_id
=places
.id
andcontacts
= (select * whereid
= 2223)) >= 1)
I know it is missing "from" citites
but I do not know how to achieve it.
with() function is used to eager load in Laravel. Unless of using 2 or more separate queries to fetch data from the database , we can use it with() method after the first command. It provides a better user experience as we do not have to wait for a longer period of time in fetching data from the database.
Eloquent ORM is best suited working with fewer data in a particular table. On the other side, query builder takes less time to handle numerous data whether in one or more tables faster than Eloquent ORM. In my case, I use ELoquent ORM in an application with tables that will hold less than 17500 entries.
Laravel includes Eloquent, an object-relational mapper (ORM) that makes it enjoyable to interact with your database.
BelongsTo is a inverse of HasOne. We can define the inverse of a hasOne relationship using the belongsTo method. Take simple example with User and Phone models. I'm giving hasOne relation from User to Phone. class User extends Model { /** * Get the phone record associated with the user.
You have 3 options using relations:
1 most straightforward solution:
Places::whereHas('contacts',function ($q) use ($city_id){
$q->whereHas('cities', function ($q) use ($city_id){
$q->where('id', $city_id);
});
})->get();
2 the same as above but using this PR: https://github.com/laravel/framework/pull/4954
Places::whereHas('contacts.cities', function ($q) use ($city_id){
$q->where('id', $city_id);
})->get();
3 Using hasManyThrough
relation:
// Place model
public function cities()
{
return $this->hasManyThrough('City', 'Contact');
}
// then
Places::whereHas('cities',function ($q) use ($city_id){
$q->where('cities.id', $city_id);
})->get();
Having your schema it's obvious that none of the suggest or your original setup can work.
This is a many-to-many relation which in Eloquent is belongsToMany
:
// Places model
public function cities()
{
return $this->belongsToMany('Cities', 'contacts', 'places_id', 'cities_id')
->withPivot( .. contacts table fields that you need go here.. );
}
// Cities model
public function places()
{
return $this->belongsToMany('Places', 'contacts', 'cities_id', 'places_id')
->withPivot( .. contacts table fields that you need go here.. );
}
Then you can call relations like this:
$city = Cities::first();
$city->places; // collection of Places models
// contacts data for a single city-place pair
$city->places->first()->pivot->open_hours; // or whatever you include in withPivot above
Now, there's another way to setup this, in case you need also Contacts
model itself:
// Places model
public function contact()
{
return $this->hasOne('Contacts', 'places_id');
}
// Contacts model
public function city()
{
return $this->belongsTo('Cities', 'cities_id');
}
public function place()
{
return $this->belongsTo('Places', 'places_id');
}
// Cities model
public function contact()
{
return $this->hasOne('Contacts', 'cities_id');
}
then:
$city = Cities::first();
$city->contact; // Contacts model
$city->contact->place; // Places model
hasManyThrough
won't work here at all
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With