class Item extends Eloquent
{
public function hotels()
{
return $this->hasMany('Bundle', 'parent_item_id', 'item_id');
}
}
I'd generally use
public function hotels()
{
return $this->hasMany('Hotel', 'foreign_key', 'local_key);
}
Having a Bundle model and referencing it as a hotel(s) is just calling for problems for you or someone else a few months down the road...
Thanks! The thing is that Hotels is a category_id of Items. So Items are bundled with other items...
But the challenge I am facing is that I cant use ->select() while doing ->hasMany().
Of course because you have to include the needed primary/foreign keys used by the relationship
I have batted my head against the same brick wall with a very similar legacy solution and have sympathy but I think this is a DB design issue. It does not conform to the standard relationships.
just to be clear....the ->hasMany() works fine...the issue i have is that the ->select(item_id, item_name) DOES NOT work.
What is happening right now is that i get a response like this...
{
"status": "OK",
"code": 200,
"data": {
"item_id": 20,
"category_id": 2,
"name": "bla bla bla ",
"description": " text text text picture text picutres",
"created_at": ,
"updated_at": ,
"hotels": [
{
"item_id": 21,
"category_id": 2,
"name": "Hotel 1",
"description": " text text text picture text picutres",
"created_at": ,
"updated_at": ,
},
{
"item_id": 22,
"category_id": 2,
"name": "Hotel 2 ",
"description": " text text text picture text picutres",
"created_at": ,
"updated_at": ,
}
],
"flights": [
{
"item_id": 23,
"category_id": 2,
"name": "YUL to JFK ",
"description": " text text text picture text picutres",
"created_at": ,
"updated_at": ,
},
{
"item_id": 24,
"category_id": 2,
"name": "FRA to MOW ",
"description": " text text text picture text picutres",
"created_at": ,
"updated_at": ,
}
]
}
}
but i want this...
{
"status": "OK",
"code": 200,
"data": {
"item_id": 20,
"category_id": 2,
"name": "bla bla bla ",
"description": " text text text picture text picutres",
"created_at": ,
"updated_at": ,
"hotels": [
{
"item_id": 21,
"name": "Hotel 1",
},
{
"item_id": 22,
"name": "Hotel 2 ",
}
],
"flights": [
{
"item_id": 23,
"name": "YUL to JFK ",
},
{
"item_id": 24,
"name": "FRA to MOW ",
}
]
}
}
as you can see in the second response, there is less data. I wanted to use ->select() but i get a empty array
You are going against MVC here. It seems like you are trying to decide what parts of the Model you want to display to the user at the model layer.
If I were implementing this I would take 1 of two solutions.
Heres a trivial example.
public function show($id)
{
$item = Item::find($id) //Probably fetched in another way
return Response::json([
'status': 'ok'
'code': 200
'data': with(new ItemPresenter($item))->toArray()
]);
}
public function toArray()
{
$attributes = $this->attributesToArray();
$relationMapper = function($item) { return [
'item_id': $item->id,
'name': $item->name
]);
return array_merge($attributes, [
'hotels': $this->hotels->map($relationMapper)->toArray(),
'flights': $this->flights->map($relationMapper)->toArray()
]);
}
As I mentioned earlier you should add all keys used in your select.
But your relationships methods are not ok, this is not a place to setup a join or a where clause. I fact i don't understand why you pour the join in your relationship method.
It looks like your items has many bundles that has many hotels, so define these relationships and then :
class Item extends Eloquent{
public function bundles(){
return $this->hasMany('Bundle', ... your keys here);
}
}
class Bundle extends Eloquent{
public function hotels(){
return $this->hasMany('Hotel', ... your keys here);
}
}
$item = Item::find($id);
foreach(item->bundles as $bundle){
foreach($bundle->hotels as hotel){
...
}
}
Thank you guys. I added the table structure and sample info for you to understand what this looks like.
There is still a problem with this. I do not consider this fixed. I ran into same issues that extjac had. for $this->hasMany('Model', 'foreign_key') -> indeed Eloquent is returning correct entities but if you try to apply a select condition it does not return anything.
Let's have an example:
When you try to get an album like http://domain.com/api/album/{album} -> you want also all pictures from that album like :
"id":"123",
"name":"My Album",
"pictures":[{
"id":"1",
"name":"Pic1",
"size":"1000"
},{
"id":"2",
"name":"Pic2",
"size":"2000"
}]
Above is the response when using:
$this->hasMany('App\Pictures', 'album_id');
But in this case i don't want size to be in the response and i don't want to fetch it as array and do extra work to remove my size.
For belongsTo condition we can use ->select('column1', 'columns2') option but when comes using it with hasMany, it simply does not work and as a result the returning data looks like this
"id":"123",
"name":"My Album",
"pictures":[]
Above is the response when using:
$this->hasMany('App\Pictures', 'album_id')->select('id', 'name');
Instead of :
"id":"123",
"name":"My Album",
"pictures":[{
"id":"1",
"name":"Pic1"
},{
"id":"2",
"name":"Pic2"
}]
I don't know if this will help anyone, but I've just suffered with exactly the same issue, and managed to solve it with: http://stackoverflow.com/questions/30216763/laravel-many-to-many-unexpected-result-set-on-select/30218621#30218621 - Basically as it's already been stated, you must supply at least one selectable key that laravel can use to map the data together. See my answer on SO for the full details. Kept me thinking for a couple of hours! :)
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community