Hasmany with child of child in laravel 5.5 - laravel

I have 3 tables.
shops
shop_foods
foods
I need to fetch foods table data when I create hasmany relation with shops_food and store.
$this->hasMany('App\Diet\ShopFood', 'shop_id', 'id');

Please, show your code so we can know what are you trying to do.
But what I can see here is that you have a wrong relationship.
Why are you assigning hasMany in a Many to Many relationship?
In your Shop Model you can make a foods relationship with:
$this->belongsToMany('App\Diet\Food);
Then you can retreive you food when calling
$shop->foods
And the shop_foods with the Pivot property

If i understand correctly you want to get foods when you call shops->shop_foods. if is that
//first you call your shops as you want.
Shop::with(['shops_food' => function($query){
//the 'shops_food' relationship should be called within an array
//this way you could query the relationship as the eloquent model.
//that way you could call the 'foods' relationship inside the shops_food relationship.
$query->with('foods')
}])
...
Note that you must have the relationship declared in shop and shop_foods models
lets your models are like these
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Shop extends Model
{
//
public function shops_food()
{
//shop_id is the foreing key inside your shop_foods table
return $this->hasMany('App\ShopFood','shop_id');
}
....
}
then ShopFood Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ShopFood extends Model
{
//
public function foods()
{
//shop_food_id is the foreing key inside your foods table
return $this->hasMany('App\Food','shop_food_id');
}
....
}

This reads as if you want
public function foods() {
$this->hasMany('App\Diet\Food');
}
in your ShopFood model and in your Shop model
public function shopfoods() {
$this->hasMany('App\Diet\ShopFood')->with('foods');
}
You can also make 2 separate relations in the Shop model:
public function shopfoods() {
$this->hasMany('App\Diet\ShopFood');
}
public function shopfoodsWithFoods() {
$this->hasMany('App\Diet\ShopFood')->with('foods');
}
So that way you can use whatever you need at that moment.
But the whole thing is really not clear...
I am not even sure how the 3 table are connected, so the hasMany are just guesses.
Nevertheless you can just go with the "with" function.
PS
There is also the possibility to just declare
protected $with = ['foods'];
in your ShopFood model, if you ALWAYS want those 2 connected. It's all in the documentation.

Related

Receiving all parents as a Child

Given those simple tables:
Parent
id
child_id
1
1
2
1
3
2
Child
id
value
1
value_x
2
value_y
3
value_z
I would like to be able to get all parents as a relation. There is no pivot table involved in this scenario. Something like this:
[Child#1] -- call relationship parents() --> receive Parent#1 and Parent#2
I think the closest idea to solve this is by using a belongsToMany relationship - but i cannot figure out the exact parameter calls to get it work.
[Edit] for a better understanding this example might help: Assuming Parent is a document scan. Which is made by the scanner which is the child. So a scan can only be done by one scanner. But a scanner can of course scan multiple documents.
Any help is very appreciated
When you have a table with a *_id field, the relationship will be belongsTo which in turn means the other relationship will be hasMany (or hasOne).
NB This is only when you wanting to relate two table i.e. not via a pivot table and not when it's a polymorphic relationship.
This is the what the relationships will look like:
class Parent extends Model
{
public child()
{
return $this->belongsTo(Child::class);
}
}
class Child extends Model
{
public parents()
{
return $this->hasMany(Parent::class);
}
}
the DB structure is seems not correct
there should be paren_id in child table
create a parent Eloquent model class
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Parent extends Model
{
public children()
{
return $this->hasMany(Child::class);
}
}
create a child class
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Child extends Model
{
public function parents()
{
return $this->belongsTo(Parent::class);
}
}
and you can get parent like this
$data = Child::with('parents')->get();

Laravel Polymorphic Relationships - Return child with parent

I have a model Team with has a polymorphic relationship with Marketcenters Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
public function teamable()
{
return $this->morphTo();
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Marketcenter extends Model
{
public function teams()
{
return $this->morphMany('App\Team', 'teamable');
}
}
I need to retrieve all teams for one or any Marketcenter so I can list all Teams and to which Marketcenter they belong.
So I execute the following code and I get a collection od Teams for the Market Center in query:
$marketcenters = Marketcenter::where('id', $request->user()->marketcenter->id)->with('teams')->get();
foreach($marketcenters as $marketcenter) {
dd($marketcenter->teams);
}
But my problem appears when I want to retrieve each Team with their corresponding Market Center:
$marketcenters = Marketcenter::where('id', $request->user()->marketcenter->id)->with('teams')->get();
foreach($marketcenters as $marketcenter) {
dd($marketcenter->teams->marketcenter->mc_name);
}
Property [marketcenter] does not exist on this collection instance.
How can I retrieve parent data to child record in a Polymoprphic relationship?
Regards
Try querying for teams instead of the market center:
$teams = Team::whereHas('teamable', function ($q) {
$q->whereKey(request()->user()->marketcenter->id);
})->get();
Also, from the Laravel docs:
You may also retrieve the owner of a polymorphic relation from the polymorphic model by accessing the name of the method that performs the call to morphTo.
// This gets the marketcenter
$team->teamable
my question is why you want to access "marketcenter" via team model like $marketcenter->teams->marketcenter->mc_name instead you can directly use $marketcenter->mc_name in the for loop as both would return you the same object.
If you still need it than you have to have another foreach loop for martketcenter->team as you have morphMany so it would return you collection object from team model if you want marketplace than you have to call teamable function that would return the object of morphed model which may be Marketcenter or may not be depending on the morphed model attached to that record

How to get all records(related and non related) of Laravel belongsTo relationship?

How can I get all the records from the relationship? I mean not only the related records, but also the rest.
Let's say I have a post which belongs to some category. If I want to change the category of this post I need a list of all available categories. Can I get this list from the relationship?
The Post model:
class Post extends Model
{
public function category()
{
return $this->belongsTo('App\Category');
}
}
The Category model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function posts()
{
return $this->hasMany('App\Post');
}
}
In the PostsController I tried:
$postModel->category->find('all'); // Returns null
$postModel->category->all(); // Returns only the related categories
I know I can simply use the Category model in the PostsController, but I prefer to do it using the relationship.
If you feel you must use the relationship to get to the other model you could try:
$categories = $post->category()->getRelated()->get();

Laravel One-to-Many and One-To-One relationship between the same tables

I have 2 tables:
Tourists,
Tours. (and corresponding models Tourist, Tour).
I have successfully set up many-to-many relationship between them. When I
$tour->tourists()->attach($tourist);
It creates a new record in a table Tour_Tourists. (tour_id, tourist_id, created_at, updated_at). It shows which tourists go with the particular tour.
Now I need to create another entity: Buyer. The buyer is one of the Tourists who pays for the Tour. Only one of the tourists belonging to the tour can be a Buyer.
I have set up one-to-one relations in both models:
<?php
namespace App;
class Tour extends Model
{
public function tourists() {
return $this->belongsToMany('App\Tourist')
->withTimestamps();
}
public function buyer() {
return $this->hasOne('App\Tourist')
->withTimestamps();
}
}
(and the same in Tourist model, except i changed 'App\Tourist' to 'App\Tour':
public function buyer() {
return $this->hasOne('App\Tour')
->withTimestamps();
)
but when I do:
$tour->buyer()->($tourist)
(where $tour and $tourist contain respective records from database), i get:
BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::withTimestamps()'
I have a feeling that I am doing it totally wrong. Can anyone just point out the direction I should move on to?
thank you.
withTimestamps() is a method used for belongsToMany only because it updates the created_at/updated_at fields of the pivot table. hasOne won't have this method.

Laravel model: instance or relationship?

I'm not a professional programmer, so I don't know that I'm describing this very well.
Eloquent relationships are established in the model, using syntax and functions such as ... - >belongsTo.. etc.
Behind these models, are tables in my database.
In my (laravel) application, I have a logged in user who needs certain information about other users. At the end of the day, they're all just users, persisting in the user's table.
So when I use a relationship to another object, (e.g. car) all is good. When I try use a relationship to another user I get errors like Cannot redeclare class App\Models\User.
I think I'm misunderstanding something here.
I get the feeling maybe I should be 'instantiating' another version of my User (as 'manager') ... But do I really need to? It's more of a lookup than anything else. I'm not sure I would even know how to do that.
Some pointers please?
It sounds like you created two distinct "User" models:
// /app/User.php:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// ...
public function user() {
return $this->hasOne('App\Models\User');
}
}
// /app/models/User.php:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// ...
public function user() {
return $this->belongsTo('App\User');
}
}
Instead you want to have a single class which belongs to itself:
// /app/User.php:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// ...
public function parent() {
return $this->belongsTo('App\User');
}
public function children() {
return $this->hasMany('App\User');
}
}
Then in your database make sure that the users table has a user_id property (edit database/migrations/2014_10_12_000000_create_users_table.php):
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
Now you can attach users to one another:
<?php
$manager = new User();
$employeeOne = new User();
$employeeTwo = new User();
$manager->children()->saveMany([
$employeeOne,
$employeeTwo
]);
dd( $employeeTwo->parent->name ); // Manager's name

Resources