Multiple relationship between tables in Laravel 5.4 - php

I have 3 tables (items, category_questions_mapping and category_questions) in mysql database in which I have the following columns:
items table has following columns:
item_id, uuid, radius, category_id
category_questions_mapping has following columns:
category_id, category_question_id
category_questions has following columns:
category_question_id, data
I have created the model for the items table which is Items.php in which I have created the following method:
public function category_questions() {
return $this->hasOne('App\CategoryQuestionsMapping','category_id','category_id');
}
The above method is basically a relationship between category_id of the items table with the category_id of category_question_mappings table
Problem Statement:
I am wondering what changes I should make in the above method so that I am able to pull data column value from category_questions table. Is there any we can make a relationship in the above method so that it can pull the data column ?
The above method will be used in the controller for display.

To acess the category_question table columns you must define the relationship on the category_question_mapping model too, like:
public function category_questions() {
return $this->hasOne('App\CategoryQuestions','category_question_id','category_question_id');
}
then acess the field you want like $items->category_questions_mapping->category_questions->data.
By the way, I'd recommend naming the first relationship you showed like category_questions_mapping() as it is linking with the category_questions_mapping table.

You can't change only the category_questions method to solve the problem. But you can make 2 relations in 2 models and query data through 2 relations.
// App\Item
public function category_questions_mapping() {
return $this->hasOne(CategoryQuestionsMapping::class, 'category_id', 'category_id');
}
// App\CategoryQuestionsMapping
public function category_question() {
return $this->hasOne(CategoryQuestion::class, 'category_question_id', 'category_question_id');
}
// Somewhere else
// Get data:
$data = $item->category_questions_mapping->category_question->data;
// Find by data:
$items = \App\Item
::whereHas('category_questions_mapping.category_question', function ($query) {
$query->where('data', 'foo');
})
->get();

Your relationship use like this :
public function category_questions() {
return $this->belongsToMany('App\CategoryQuestions','category_questions_mapping','category_id', 'category_question_id);
}

Related

laravel hasMany on two columns

hi im using laravel 7 i've the relation in the user model called get_journal_entry_lines
public function get_journal_entry_lines()
{
return $this->hasMany('App\Models\Journal_entry_line','user_id','id')->orderBy('date','asc');
}
sometimes the user in column called user_id and sometimes on other column called partner_id
so is it possable to do something like this in laravel
public function get_journal_entry_lines()
{
return $this->hasMany('App\Models\Journal_entry_line','user_id','id')->orderBy('date','asc')->orWhere('partner_id','=','id');
}
get Journal_entry_line from columns user_id and partner_id at same relation .
Can't you just create 2 different relations?
For example, you could use the one below for your users:
public function get_journal_entry_lines_for_users()
{
return $this->hasMany('App\Models\Journal_entry_line','user_id','id')->orderBy('date','asc')->orWhere('partner_id','=','id');
}
and this one for your partners:
public function get_journal_entry_lines_for_partners()
{
return $this->hasMany('App\Models\Journal_entry_line','partner_id','id')->orderBy('date','asc');
}

Laravel attach pivot data without errors

I a have pivot table and a relation on model Product:
public function product_bodies()
{
return $this->belongsToMany(static::class, 'product_bodies')->withPivot('product_id', 'product_body_id');
}
In the controller when I want to attach data:
$products = ['sadasdasd', 'asdasda', 'asdasd', 'asdasd']; //for column product_body_id
$product = Product::create($request->all());
$product->product_bodies()->attach($products);
I get the error:
General error: 1364 Field 'product_body_id' doesn't have a default
value
If I do this:
public function product_bodies()
{
return $this->belongsToMany(static::class, 'product_bodies', 'product_id', 'product_body_id')->withPivot('product_id', 'product_body_id');
}
Then all works well. But then I can't get pivot data with:
$product->product_bodies;
I get empty items..
How can I fix this problem?
Table product_bodies has 3 columns:
id
product_id
product_body_id
In product_body_id I pass strings.
I have 3 ideas:
You need to replace static::class to '\App\ProductBody' or ProductBody::class
public function product_bodies()
{
return $this->belongsToMany('\App\ProductBody', 'product_bodies')->withPivot('product_id', 'product_body_id');
}
$products must be array of product bodies ids.
$productBodiesIds = [1, 55, 66];
$product->product_bodies()->attach($productBodiesIds);
Maybe, sync instead of attach will be a better solution.

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.

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');
}

Laravel eager relationships empty query

I have 3 tables : hotels, hotels_data, hotels_types
Table hotels have id, type, stars, etc... type field is set as foreign key referencing type_id in hotels_types. I'm managing to get the correct data from hotels_data but have an empty result on getting hotels_types title and I don't understand why.
The code is the following :
class Hotel extends Eloquent {
public function getList() {
$data = Hotel::select('id','stars')->with('HotelData', 'HotelType')->paginate(10);
return View::make('hotels.index')->with('hotels', $data);
}
public function HotelData()
{
return $this->hasOne('HotelsData')->select('id','hotel_id','title');
}
public function HotelType()
{
return $this->hasOne('HotelType','type_id', 'type')->select('id','type_id','title');
}
}
You're using the wrong relationship for HotelType()
Your Hotel model should use the inverse of hasOne, which is belongsTo, because it contains the foreign key to HotelType (when a table contains a foreign key, it always belongs to the table being pointed to).
The following should work:
public function hotelType() {
return $this->belongsTo('HotelType','type', 'type_id')->select('id','type_id','title');
}
I've obtained the desired result with the following:
Hotel::select('hotels.*','hotels_types.title as type')
->join('hotels_types', 'hotels.type', '=', 'hotels_types.type_id')
->with('HotelData');

Categories