Laravel Eloquent for hasMany relation cannot find records - laravel

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

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 relationship "fallback"

class Price extends Model {
public function priceable() {
return $this->morphTo();
}
}
class Venue extends Model {
public function events() {
return $this->hasMany('App\Event');
}
public function price() {
return $this->morphOne('App\Price', 'priceable');
}
}
class Event extends Model {
public function venue() {
return $this->belongsTo('App\Venue');
}
public function price() {
return $this->morphOne('App\Price', 'priceable');
}
}
What is the best way to have a fallback, if the event doesn't have a price assigned, to get it to use the event's venue price?
Is there a logical way to make this as a relation or should I just do everything in the Controllers?
You can set a default model with optional custom values directly from the relation. This default model can be populated either from an array or an anonymous function:
public function price()
{
return $this->morphOne('App\Price', 'priceable')->withDefault([...]);
}
You can refer to Laravel's documentation about default models for some more explanation.
class Event extends Model {
...
public function getEventPriceAttribute() {
return $this->price > 0 ? $this->price : $this->venue()->price
}
...
}
By doing this, you can call Event object and get the price like this:
$eventObject->eventPrice;

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.

HasManyThrough with polymorphic and many-to-many relations

In my Laravel application I have the following classes:
class Product extends Model
{
public function extended()
{
return $this->morphTo();
}
public function users {
return $this->belongsToMany('App\User', 'products_users', 'product_id');
}
}
class Foo extends Model
{
public function product()
{
return $this->morphOne('App\Product', 'extended');
}
public function bars()
{
return $this->hasMany('App\Bar');
}
}
class Bar extends Model
{
public function product()
{
return $this->morphOne('App\Product', 'extended');
}
public function foo()
{
return $this->belongsTo('App\Foo');
}
}
class User extends Model
{
public function products()
{
return $this->belongsToMany('App\Product', 'products_users', 'user_id');
}
}
I can easily get users of a bar object using Bar::find(1)->product->users and I can also get the bars of a user with User::find(1)->products.
How can I get the users of all bars belonging to a specific foo? That is, Foo::find(1)->users should return all users that have the bars belonging to Foo with id 1. It's basically hasManyThrough with polymorphic and many-to-many relations.
Try something like this:
public function users()
{
$Foo = static::with(['bars', 'bars.products', 'bars.product.users'])->get();
return collect(array_flatten(array_pluck($Foo, 'bars.*.product.users')));
}
This should work for you (code has been tested, but not against the exact same structure as your setup). The first line will return all the users deeply nested through the relationships. The second line will pull out the users, flatten them into an array, then transform the array into a collection.
I created a HasManyThrough relationship for cases like this: Repository on GitHub
After the installation, you can use it like this:
class Foo extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function users() {
return $this->hasManyDeep(
User::class,
[Bar::class, Product::class, 'products_users'],
[null, ['extended_type', 'extended_id']]
);
}
}

Laravel polymorphic relationship

I have different Database tables and below is the DB Diagram.
I am trying to make a many to many polymorphic relationship, but no luck, Please guide me that what i need to do, means where i need to add which type relationship/code?
Course Model
class Course extends Eloquent {
public function quizzes()
{
return $this->morphToMany('Quiz', 'quizzable');
}
}
Chapter Model
class Chapter extends Eloquent {
public function quizzes()
{
return $this->morphToMany('Quiz', 'quizzable');
}
}
Lesson Model
class Lesson extends Eloquent {
public function quizzes()
{
return $this->morphToMany('Quiz', 'quizzable');
}
}
Quiz Model
class Quiz extends Eloquent {
public function courses()
{
return $this->morphedByMany('Course', 'quizzable');
}
public function chapters()
{
return $this->morphedByMany('Chapter', 'quizzable');
}
public function lessons()
{
return $this->morphedByMany('Lesson', 'quizzable');
}
}
Source: http://laravel.com/docs/4.2/eloquent#many-to-many-polymorphic-relations
I would change the quizzes_assigned table to:
Table name: quizzables
quiz_id - integer
quizzable_id - integer
quizzable_type - string

Resources