Laravel Eloquent get a relation that matches a value in pivot table - php

I need to get model that must match with the value stored in a pivot table, but unfortunately i couldn't get the solution.
Here is my schema
PEROPERTY TABLE
id
FILTER TABLE
id
FILTER_OPTION TABLE
id
filterId
FILTER_OPTION_TRANSLATE TABLE
optionId
languageId
title
PROPERTY_FILTER TABLE
propertyId
filterId
optionId
What i wanto to do is:
#foreach($property->filters as $filter)
{{ $filter->option->translate->title }}
#endforeach
but here the problem for me is how to say get option matches optionId in PROPERTY_FILTER TABLE
My models:
PROPERTY MODEL
public function filters()
{
return $this->belongsToMany(Filter::class, 'PROPERTY_FILTER','propertyId','filterId');
}
FILTER MODEL
public function option()
{
return $this->hasMany(Filter_Option::class, 'filterId');
}
FILTER OPTION MODEL
public function translate()
{
return $this
->hasOne(Filter_Option_Translate::class, 'optionId')
->where('langId', currentLanguage()->langId);
}
I hope i can get some help, thanks from now.

I solved my problem by using pivot table as seperated model.
I was trying to get 3 level far relation through pivot table but even intermediate model couldn't solve my problem, and i just tried a seperated model.
Firstly, i created Property_Filter model that represents property_filter pivot table and I added filter and option methods as below shown:
public function filter()
{
return $this->belongsTo(Filter::class, 'filterId');
}
public function option()
{
return $this->belongsTo(Filter_Option::class, 'filterValue');
}
Then converted filters relationship method
public function filters()
{
return $this->belongsToMany(Filter::class, 'PROPERTY_FILTER','propertyId','filterId');
}
to
public function filters()
{
return $this->hasMany(Property_Filter::class,'propertyId');
}
Now i reach the filter and option selected for iterated filter like below shown:
#foreach($properties as $property)
#foreach($property->filters as $filter) // here i get filters chosen for iterated property
<span class="caption">{{ $filter->filter->translate->entryTitle }}</span> // here i get iterated filters title (translated)
<span class="value">{{ $filter->option->translate->entryTitle }}</span> // here i get chosen option for iterated filter not all options belognsto iterated filter
#endforeach
#endforeach

Related

Model connections is not working properly - Laravel

I'm trying to display a tag that is selected by the user. The tag name is in the tags table. The tagpost table has the mapping between the tag and the user.
The following is the User model, where the primary key in users table is id, and var_id can be many types and 2 is for users (not sure if the below where condition is correct):
public function tagpost()
{
return $this->hasMany('App\tagpost', 'var_id')->where('type',2);
}
The following is the tagpost model:
public function tags()
{
return $this->belongsToMany('App\tag','id');
}
public function users()
{
return $this->belongsToMany('App\User');
}
The following is the tag model :
public function tagposts()
{
return $this->hasMany('App\tagpost', 'var_id');
}
The following query is not working in the blade :
<option>{{ Auth::user()->tagpost()->tags()->select('t_name')->first()->t_name}} </option>
Error in blade :
Call to undefined method Illuminate\Database\Query\Builder::tags()
You are calling the relations as method whereas they should be called as property like this. Also i suggest you the laravel documentation
<option>{{ Auth::user()->tagpost->tags->select('t_name')->first()->t_name}} </option>
If tagpost is just the relation table why don’t you define a method tags() on the User model, using the tagposts table as the pivot so you can just do Auth::user()->tags()?
Your code won’t work because ->tagpost() returns the Relation itself and not the tagpost models...

Laravel - Query builder get relation

In my project I have a Polymorphic relation. This relation is as followes:
Plugins
id - integer
composer_package - string
Themes
id - integer
composer_package - string
Products
id - integer
name - text
...
commentable_id - integer
commentable_type - string
When I need to display all the products that are a Theme I do the following:
$themes = DB::table('products')->orderBy('id', 'asc')->where('productable_type', Theme::class)->get();
The code above provides me with a list of all the products where the productable_type field is filled with App/Theme, I display them with a foreach loop like this #foreach($themes as $theme). Now my problem is.
I need to get the composer_package from the themes table that belongs to that product. So say for instance. I get a product from the products table where the productable_id is 3. I want the value of the composer_package field in the themes table where the ID is 3. When I do {{ $theme->products->composer_package }} or {{ $theme->composer_package }} It gives me the error Undefined property What is causing this?
This is my product model
public function product()
{
return $this->morphTo();
}
public function order_items()
{
return $this->hasMany(Orderitems::class);
}
And this is my theme model
public function webshops()
{
return $this->hasMany(Webshop::class);
}
public function products()
{
return $this->morphMany(Product::class, 'productable');
}
Thanks in advance!
Is there any reason you are using the DB facade to pull data instead of the actual models?
One issue your are having is that your polymorphic relationship is stored in the commentable_id / commentable_type field, while your function name is product. Laravel does some of its magic just by naming alone, so let's make sure the column names and polymorphic function names match up in the product model:
public function commentable()
{
return $this->morphTo();
}
After that, try something like this in the controller:
$themeProducts = Product::where('commentable_type', Theme::class)->get();
And this in the view
#foreach ($themeProducts as $themeProduct)
{{ $themeProduct->commentable->composer_package }}
#endforeach
Your table has "commentable", but your model is looking for "productable". You're also missing a method.
in your product model add:
public function commentable(){
return $this->morphTo();
}
in your theme model modify the products() method to:
public function products(){
return $this->morphMany(Product::class, 'commentable');
}
You could also update your commentable_type and commentable_id columns in your table to productable_type and productable_id, in which case you need to rename commentable() in the code for the product model above to productable(), and 'commentable' to 'productable' in the code for the theme model above.
(Source: https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations)
Create relations with the model as mentioned in above answers, then you can retrieve relations using with helper.
E.g.:
Product::where('commentable_type', Theme::class)->with('commentable')->get();
and then can directly use as mentioned above.
e.g.: $themeProduct->commentable

Get column list with Eloquent relation in laravel

I want to get column list with Eloquent relation in laravel.
When I use this comman
$columns = Schema::getColumnListing('news');
Result is all fields of news table but I want to get relation fields for CategoryNews table.
News model:
public function NewsCategories()
{
return $this->belongsTo('App\CategoryNews');
}
CategoryNews model:
public function News()
{
return $this->hasMany('App\News');
}
You should be able to do something like this:
$columns = Schema::getColumnListing($news->NewsCategories()->getRelated()->getTable()));
Using getRelated() method you are getting related object for relationship (in your case it's App\CategoryNews) and now using method getTable() you can get table name for this model and you can use this table name for getColumnListing() method.

Query foreign key data from Blade template

I have two models: MenuCategory and MenuItem, I want to display MenuItem data on my blade page along with its MenuCategory. I know its possible to do this by adding it to the return data in my controller however I would like to do it leveraging Eloquent instead, however I receive errors.
Here are my codes:
MenuCategory model
public function items()
{
return $this->hasMany('App\MenuItem');
}
MenuItem model
public function category()
{
return $this->belongsTo('App\MenuCategory');
}
Controller
public function show($id)
{
$item = MenuItem::findOrFail($id);
return view('menu.admin.single', compact('item'));
}
Blade Page
{{ $item->category->name }}
UPDATE:
Table menu_item
id
name
menu_category_id
Table menu_category
id
name
When using all the above I get the following error:
Trying to get property of non-object
This error is due to the naming convention of Eloquent.
Provide the optional foreign key variable in your relationship method to make it work, ie.
$this->belongsTo('App\MenuCategory', 'menu_category_id');
Probably every Item doesn't contain a related category but to make sure you may try something like this, it'll try to retrieve the name only if there is a related category is available:
{{ $item->category ? $item->category->name : 'No Name or empty string' }}
Alternatively you may try something like this:
$item = MenuItem::has('category') // check if there is a related category
->with('category') // if yes then load it with that category
->findOrFail($id);
You used a different foreign key than Laravel expect so explicitly mention it like:
public function category()
{
return $this->belongsTo('App\MenuCategory', 'menu_category_id', 'id');
}

Retrieving a single colum from a pivot table - Laravel 5

I am using a pivot table genre_user to relate user to genre.
table contains the following fields
id
user_id
genre_id
Following are the model definitions
User.php
public function genres() {
return $this->belongsToMany('App\Genre');
}
Genre.php
public function artists() {
return $this->belongsToMany('App\User');
}
I am getting the results as a collection when I use the following code
$user = auth()->user();
dd($user->genres);
I want to show the selected genres in a dropdown field of genres. Is it possible to get only the current users genre_id as an array from the pivot table without using a foreach loop.
I think what will help you achieve this behavior is the lists() method.
Try something like
$user_genres = auth()->user()->genres()->lists('name','id');
If you are using Forms & HTML package you can just do
{!! Form::select('genres',$user_genres,null) !!}
And here is your dropdown
More info here (scroll down to "Retrieving A List Of Column Values")
A user should have one genre.
Therefore, your models should contain the following relations:
User.php
public function genre() {
return $this->hasOne('App\Genre');
}
Genre.php
public function artists() {
return $this->belongsToMany('App\User');
}

Categories