Laravel sub-relationship - laravel

I have the following models:
class Recipe extends Model
{
public function parts() {
return $this->hasMany('App\RecipePart');
}
}
class Ingredient extends Model
{
protected $fillable = [
'name','image'
];
}
class RecipePart extends Model
{
public $timestamps = false;
public function ingredients()
{
return $this->hasMany('App\RecipePartIngredient');
}
}
In my controller, I want to return a recipe with all recipe parts belongs to him, and all ingredients belong to each recipe part. The following code works, but...:
return Recipe::with('parts.ingredients')
->where('id',$request->id)->first();
It works, my parts.ingredients returns the data in my recipe_part_ingredients table, which is OK, but I want for each ingredient_id - return the ingredient information from my ingredients table. (name, image).
Any idea how I can do this? I tried to add the following code to my RecipePartIngredient, but no luck:
public function ingredient() {
return $this->hasOne('App\Ingredient');
}

You must use
belongsTo method like That:
public function ingredient() {
return $this->belongsTo('App\Ingredient');
}

How about this:
return Recipe::with('parts.ingredients')
->with('parts.ingredients.ingredient')
->find($request->id);

Related

Get parent relation of an object dynamically in Laravel / Eloquent

I have three models
Product, Variant and Option.
class Product {
public $id;
public function variants(): HasMany
{
return $this->hasMany(Variant::class);
}
}
class Variant {
public $id;
public $product_id;
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
public function options(): HasMany
{
return $this->hasMany(Option::class);
}
}
class Option {
public $id;
public $variant_id;
public function variant(): BelongsTo
{
return $this->belongsTo(Variant::class);
}
}
I want to know if there is a way for an instance of Variant to get parent (Product) relationship and for Option
the parent (Variant) relationship with one line of code. Is there anything like the below?
$instance->parent();
I want to avoid writing
If (get_class($instance) === 'Variant' ) {
$instance->product();
} else if (get_class($instance) === 'Option' ) {
$instance->variant();
}
You can get the relation model easily. Like-
$variants = \App\Models\Variant::latest()->get();
foreach($variants as $variant)
{
$product_name = $variant->product->name; // this will be the product name that that related with this variant
}
It will be also work for single collection
$variant = \App\Models\Variant::find(1)>-first();
$variant->product;// this is product model instance that related to variant

Laravel hasMany relationship issue

I have a problem about table relationship in models. when I try to add hasMany relation there is an error popping up.
Call to undefined relationship [Plan100] on model [App\AllPlan].
This is the main table model places
protected $table = "places";
public $with = ["AllPlan"];
public function allplans()
{
return $this->hasMany("App\AllPlan");
}
And AllPlan table model
protected $table = "all_plans";
public function place()
{
return $this->belongsTo("App\Place");
}
No problem 'till here. I can see the AllPlan data inside the Places table on json response... But, the problem is popping up when I try to add hasMany relation into AllPlan table like below.
Now AllPlan table model looks like this.
protected $table = "all_plans";
public $with = [
"Plan100",
"Plan90",
];
public function place()
{
return $this->belongsTo("App\Place");
}
public function plan()
{
return $this->hasMany(
"App\Plan100",
"App\Plan90"
);
}
And the Plan100 table model look like this:
public function plan()
{
return $this->belongsTo("App\AllPlan");
}
But it's giving me an error. But I am not very sure where do I do wrong. Thank you.
Seems to me that you are trying to create two new relations, but this can't be done inside one function. Create two functions and refactor your code like this:
public function plan100()
{
return $this->hasMany(App\Plan100", 'foreign_key');
}
public function plan90()
{
return $this->hasMany(App\Plan90", 'foreign_key');
}

How to get data from table related through pivot table?

I have 4 tables: countries, activities, country_activities and packages.
countries and activities are related through pivot table country_activity, and packages is related to country_activity.
Now, How do I eager load all packages related to each activity in a country?
class Country extends Model
{
public function activities() {
return $this->belongsToMany('App\Models\Activity','country_activities')->using('App\Models\CountryActivity')->as('country_activities');
}
}
class Activity extends Model
{
public function countries() {
return $this->belongsToMany('App\Models\Country','country_activities')->using('App\Models\CountryActivity')->as('country_activities');
}
}
class Package extends Model
{
public function country_activities() {
return $this->belongsToMany('App\Models\CountryActivity');
}
}
class CountryActivity extends Pivot
{
protected $table = 'country_activities';
public function packages() {
return $this->hasMany('App\Models\Package');
}
}
So, this worked for me.
class Country extends Model
{
public function activities() {
return $this->belongsToMany('App\Models\Activity','country_activities')->using('App\Models\CountryActivity')->withPivot(['id'])->as('country_activities');
}
Now, In my controller, I do this
$country = Country::with(['activities'=> function($q) {$q->where('name','Trekking');}])->where('name','Nepal')->first(['id','name']);
$country->activities->map(function ($i){
$i->country_activities->load('packages');
return $i;
});
I did something similar in a project i worked on. I'm not sure it will work but it's worth the shot:
$country = Country::find(1);
$country->activities = $contry->activities()->get()->each(function ($i, $k){
$i->packages = $i->pivot->packages;
//$i->makeHidden('pivot'); -> This is useful if you want to hide the pivot table
});
var_dump($country);

Laravel Eloquent many to many relationship with translation

I have a problem with a many to many relationship and the translations of the terms.
I have 4 tables:
products
- id, price, whatever
products_lang
- id, product_id, lang, product_name
accessori
- id, active
accessori_lang
- id, accessori_id, lang, accessori_name
I'm trying to assign accessories to products with an intermediate table named:
accessori_products
this is the model for Product:
class Product extends Model {
protected $table = 'products';
public function productsLang () {
return $this->hasMany('App\ProductLng', 'products_id')->where('lang','=',App::getLocale());
}
public function productsLangAll() {
return $this->hasMany('App\ProductLng', 'products_id');
}
public function accessori() {
return $this->belongsToMany('App\Accessori', 'accessori_products');
}
}
this is the model for productLng:
class ProductLng extends Model {
protected $table = 'products_lng';
public function products() {
return $this->belongsTo('App\Product', 'products_id', 'id');
}
}
Then I have the model for Accessori:
class Accessori extends Model {
protected $table = 'accessori';
public function accessoriLang() {
return $this->hasMany('App\AccessoriLng')->where('lang','=',App::getLocale());
}
public function accessoriLangAll() {
return $this->hasMany('App\AccessoriLng');
}
public function accessoriProducts() {
return $this->belongsToMany('App\Products', 'accessori_products', 'accessori_id', 'products_id');
}
}
And the model for AccessoriLng:
class accessoriLng extends Model {
protected $table = 'accessori_lng';
public function accessori() {
return $this->belongsTo('App\Accessori', 'accessori_id', 'id');
}
}
the last model is for the relationship between the two tables above:
class ProductAccessori extends Model {
protected $table = 'accessori_products';
public function accessoriProducts() {
return $this->belongsTo('App\Product', 'accessori_id', 'products_id');
}
}
I'm trying to get the accessories of each product and to get also the translation but I'm having a lot of problem with this.
It's my first time with a many to many relation with translations too.
Can anyone put me on the right direction?
controller
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
you'll get products with accessori that has accessoriLang.

Laravel Saving A Model And Relationships

I have the following Model:
class Movie extends Eloquent {
protected $primaryKey = "movie_id";
public function detail()
{
return $this->hasOne('Detail');
}
public function firstpage()
{
return $this->hasOne('Firstpage');
}
public function country()
{
return $this->belongsToMany('Countries','movies_countries','movie_id','country_id');
}
public function year()
{
return $this->hasOne('Years');
}
public function media() {
return $this->hasMany('Media');
}
}
This is the Model of interest:
class Years extends Eloquent {
protected $table = 'movies_years';
protected $primaryKey = "relation_id";
public function movie()
{
return $this->belongsTo('Movie');
}
The DBTable for years has a field "movie_year" and "movie_id"
So, I have following problem, or understanding issue:
I'm trying to update the Model Years with new Data, but can't seem the get it done. I tried the following:
$movies = Movie::find($tmp['movie_id']);
$movies->title = $tmp['title'];
$movies->title_product = $tmp['title_product'];
$movies->title_orginal = $tmp['title_original'];
$movies->year = array('movie_year' => $tmp['movieyears']);
$movies->push();
The eye is on the $movies->year row, everything else works fine.
I also tried something stupid like:
$movies->year() = array('movie_year' => $tmp['movieyears']);
I don't know how to update the Years Model, which has a relation with the Movie Model.
The offical way would be using attach, sync or associate methods. These methods are described at http://laravel.com/docs/eloquent-relationships#inserting-related-models
In your case, you'd have to do something like this:
$movies->year()->attach($tmp['movieyears']);
To remove the relation (not the Movie or Year), use detach().

Resources