Laravel polymorphic relationships return null - laravel

I'm trying to join an Order and 2 different OrderDetailType tables.
OrderDetailType1
- id
- order_id
OrderDetailType2
- id
- order_id
Order
- id
- detail_type 'type1' or 'type2'
And I have followed Polymorphic Relations example in official Laravel site and adapted to my code like:
class OrderDetailType1 extends Model {
public function order() {
return $this->morphOne('App\Order', 'type_detail');
}
}
class OrderDetailType2 extends Model {
public function order() {
return $this->morphOne('App\Order', 'type_detail');
}
}
class Order extends Model {
public function type_detail() {
return $this->morphTo();
}
}
And I have put Relation::morphMap() into boot() function in AppServiceProvider class already.
use Illuminate\Database\Eloquent\Relations\Relation;
class AppServiceProvider extends ServiceProvider {
public function boot() {
Relation::morphMap([
'type1' => 'App\OrderDetailType1',
'type2' => 'App\OrderDetailType2'
]);
}
}
The example is different from my code. The difference is both foreign key and the attribute that specifying which table to be joined should be in Order. So I cannot use morphTo() and morphOne() like the example to solve this.
I am confuse which classes should contain morphTo() and morphOne(). And is there any overload to specify which table have foreign key and type?
I use Laravel 5.4. Thank You in Advance.

The _id column has to be in the Order table:
OrderDetailType1
- id
OrderDetailType2
- id
Order
- id
- detail_type
- detail_id
class OrderDetailType1 extends Model {
public function order() {
return $this->morphOne('App\Order', 'detail');
}
}
class OrderDetailType2 extends Model {
public function order() {
return $this->morphOne('App\Order', 'detail');
}
}
class Order extends Model {
public function detail() {
return $this->morphTo();
}
}

Related

Get all records from another table with pivot

I have three tables:
comments
id
comment_links
id | comment_id | link_id
links
id
I want to get all Links associated with each Comment. As you can see, CommentLink should act as a pivot table, but I don't know how to set up the relationships to make this work. I think I need to use the hasManyThrough relationship, but I'm not 100% sure.
Here are my current class relationships (they may be wrong):
Comment.php:
class Comment extends Model
{
public function commentLinks()
{
return $this->hasMany('App\CommentLink', 'comment_id', 'id');
}
public function links()
{
// How do I fetch all links here using the pivot table?
}
}
CommentLink.php:
class CommentLink extends Model
{
public function comment()
{
return $this->belongsTo('App\Comment');
}
public function link()
{
return $this->hasOne('App\Link', 'id', 'link_id');
}
}
Link.php:
class Link extends Model
{
public function commentLinks()
{
return $this->belongsToMany('App\CommentLink', 'link_id', 'id');
}
}
What do I need to do here to make this work?
You have the right idea, just using the wrong class names.
class Link extends Model
{
public function comments()
{
return $this->belongsToMany('App\Comment');
}
}
class Comment extends Model
{
public function links()
{
return $this->belongsToMany('App\Link');
}
}
You don't actually need to have a class for your pivot table, but you can if you want.
This is quite a good guide on how to do this.
https://laraveldaily.com/pivot-tables-and-many-to-many-relationships/

Laravel Eloquent for hasMany relation cannot find records

I can not find why it does not work.
In my Course model I have defined relation:
class Course extends Model {
public function courseDates() {
return $this->hasMany(CourseDate::class, 'course_id');
}
}
And in my CourseDate model this:
class CourseDate extends Model {
public function course() {
return $this->belongsTo(Course::class);
}
}
When I try to access CourseDates from Course I will always get null, but when I access Course from CourseDate, it works and I see all data:
var_dump(CourseDate::where('id', 1)->first()->course->name); => output: "Course 1"
var_dump(Course::where('id', 1)->first()->courseDate); => output: null
And what's strange when I try it with another course (like ID 2) then it works. The data is absolutely the same in the database. Any Ideas?
You shouldent add class like CourseDate::class instead you should add it like below
class Course extends Model {
public function courseDates() {
return $this->hasMany('App\CourseDate', 'course_id');
}
}
And in your CourseDate model
class CourseDate extends Model {
public function course() {
return $this->belongsTo('App\Course');
}
}
And your relationship method for Course model is courseDates so you should use it like below
var_dump(Course::where('id', 1)->first()->courseDates);
Documentation : https://laravel.com/docs/5.7/eloquent-relationships

Get resources with hasManyThrough a model using BelongsTo

I have the following models:
User:
- id
- name
Location:
- id
- name
- region_id
table: user_location
- user_id
_ location_id
The user belongsToMany location through that table. I also have another model:
Region
- id
- name
I defined Region hasMany Locations.
With those relationships, how do I define a relationship between User and Region which Region will be able to find all users under all Locations associated with it?
<?php
class User extends Model
{
public function locations() {
return $this->belongsToMany('App\Location', 'user_location');
}
}
class Location extends Model
{
public function users() {
return $this->belongsToMany('App\User', 'user_location');
}
public function region() {
return $this->belongsTo('App\Region', 'region_id');
}
}
class Region extends Model
{
public function locations() {
return $this->hasMany('App\Location', 'region_id');
}
public function users() {
// what am I supposed to put in here?
}
}
There is no native relationship for this case.
I created a HasManyThrough relationship for situations like this: Repository on GitHub
After the installation, you can use it like this:
class Region extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function users() {
return $this->hasManyDeep(User::class, [Location::class, 'user_location']);
}
}

Relationship: belongsTo this model or a different model

We have the following
Manager
[id]
Companies
[id]
[manager_id] not nullable
Stores
[id]
[company_id]
[manager_id] *nullable*
I am looking for a single Eloquent relationship for the manager of every store.
Any suggestions?
Building on your comment #Sanjay S
class Store extends Model {
public function manager() {
return $this->belongsTo('App\Manager');
}
public function getManager() {
if (is_null($this->manager)) {
return $this->company()->manager;
} else {
return $this->manager;
}
Then when you call $store->getManager() you will get the company manager if store manager_id is null
You question is not clear as your relationship in the stores table is like manager_id [nullable] and you are asking for a single Eloquent relationship for the manager of every store. But from my guesses your Eloquent models should be look like this
class Manager extends Model {
public function stores() {
return $this->hasMany(App\Store::class);
}
public function company() {
return $this->hasOne(App\Company::class);
}
}
Company class
class Company extends Model {
public function manager() {
return $this->belongsTo(App\Manager::class);
}
}
Store class
class Store extends Model {
public function manager() {
return $this->belongsTo(App\Manager::class);
}
}
Hope this solution works for you.

Laravel Eloquent Relationship Through Another Table

I have the following database tables:
Seasons
id
number
Teams
id
name
Standings
id
season_id
team_id
The question is, how could I get all of the teams in a season through the standings table. At the moment I am getting all of the teams this way:
$teams = [];
$standings = $season->standings;
foreach($standings as $standing){
$teams[] = $standing->team;
}
Is there a way I could do this using Eloquent relationships? I have tried HasManyThrough with no success. These are what my models look like currently:
class Season extends Eloquent{
public function standings(){
return $this->hasMany('Standing');
}
}
class Standing extends Eloquent{
public function team(){
return $this->belongsTo('Team');
}
}
class Team extends Eloquent{
public function standings(){
return $this->belongsToMany('Standing');
}
}
Your relationships look a little off. Here is all the relationships you should need though only the belongsToMany ones are required for this specific scenario of finding all the teams in a season.
class Season extends Eloquent {
public function teams()
{
return $this->belongsToMany('Team', 'Standings');
}
public function standings()
{
return $this->hasMany('Standing');
}
}
class Team extends Eloquent {
public function seasons()
{
return $this->belongsToMany('Season', 'Standings');
}
public function standings()
{
return $this->hasMany('Standing');
}
}
class Standing extends Eloquent {
public function team()
{
return $this->belongsTo('Team');
}
public function season()
{
return $this->belongsTo('Season');
}
}
You would use the belongsToMany relationship rather than a hasManyThrough to query all the teams in a season. That would look something like...
Season::with('teams')->find($season_id);
foreach($season->teams as $team) {
echo $team->name;
}

Resources