Its because $event does not belong to any category. If you dd($event->categories), it will return null
Discovering how to see what relationships are passed with Variable
Hi, I am trying to understand how to test what relationships are passed with a variable. I have a variable called event which I am showing. In the models I have created the relationships event.php
public function organizer()
{
return $this->belongsTo(Organizer::class);
}
public function categories()
{
return $this->belongsTo(Category::class);
}
in category.php
public function events()
{
return $this->hasMany(Event::class);
}
in organizer.php
public function events()
{
return $this->hasMany(Event::class);
}
in my migration tables for event I have
Schema::create('events', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('category_id')->nullable();
$table->unsignedInteger('organizer_id')->nullable();
in my category migration
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('categoryName');
in my organizer migration
Schema::create('organizers', function (Blueprint $table) {
$table->increments('id');
$table->string('organizationName');
In my blade file I was able to call
{{ $event->organizer->organizationName }}
and it shows the name of the correct organizer that is associate with the id. Yet when I try to use
{{ $event->categories->categoryName }}
I get "Trying to get property 'categoryName' of non-object. How would I go about testing to see what is wrong? If I do a dd($event) it doesn't show the attached classes such as organizer or category. Is there a way I could see what classes are attached and what info I can grab from them?
Thanks!
You can dd() the result, but if this is in a loop, you will only see the first result and then it will stop
You can use the Laravel dump server and then dump on each pass around the loop,
or you could code around it by using the null coalesce operator (see previous question here on this forum)
https://laracasts.com/discuss/channels/laravel/trying-to-get-property-of-non-object-73
It does return a null but in the database I can see that this event (id 14) has a category_id of 6
@SNAPEY - oh man, that null coalesce operator is awesome!
@chrisgrim Can you check if in categories table, the record with id = 6 is existed? Or if this is in a loop, you can check @snapey reply
@DRAGONEYES96 - Yeah in the categories table the line with an id of 6 has the name categoryName of Tillman PLC
In my controller I am passing the event and categories. Could this be causing an issue?
public function createCategory(Event $event)
{
$categories = Category::latest()->get();
return view('events.create.categoryCreate', compact('event', 'categories'));
}
My blade file
@extends('events.createWalkthrough')
@section('createGuide')
<div>
<h2> What type of Event are you hosting?</h2>
</div>
<div>
<p>Choose the category that best describes your event</p>
</div>
<div>
@include ('layouts.error')
<form method="POST" action="/create-your-event/{{ $event->slug }}/category" class="floating-form">
@method('PATCH')
@csrf
<div>
<select name="category_id" id="category_id" class="form-control" required>
@if( $event->category_id == null )
<option value="" hidden>Choose Catagory</option>
@else
<option value="" hidden>{{ $event->categories->categoryName ?? 'temp' }}</option>
@endif
@foreach ($categories as $category)
<option value="{{ $category->id}}">{{ $category->categoryName}}</option>
@endforeach
</select>
</div>
<div class="">
<button type="submit" class="slider slidein">
<div class="circle">
<span class="icon arrow"></span>
</div>
<p class="button-text">Save and Continue</p>
</button>
</div>
</form>
@endsection
@chrisgrim Well i think in controller, you should use
$event->load('categories')
to eager loading relationship. So that you can use later in blade
Hi,
So I did the eager loading and now I see that it is null. How can I test why the relationship isn't working? Is it because the name on the event table is category_id and the name of the database table is categories?
No, the column on the event table relates to the model, so category_id is fine.
Start with tinker
>>> $e = Event::load('categories')->find(14);
and in the response you should see relationship of categories and a record with id of 6
Hi @snapey
Good call! I tried to run that in tinker and got
PHP Error: Call to undefined method Illuminate/Events/Dispatcher::load() in /Users/Chris/code/showbelow/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 237
is there another option for load()?
Sorry, my mistake. In that context it should be with(). Load is the same, but where you already have the eloquent model.
>>> $e = Event::with('categories')->find(14);
@SNAPEY - Hmmm
I am also getting the same error for with().
PHP Error: Call to undefined method Illuminate/Events/Dispatcher::with() in /Users/Chris/code/showbelow/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 237
When I tried to google this all I can find is something about firing() not working either,
Depending on the situation in a for each Loop you may still want to show all parents.
Take as an example An accounts receivable report, Acme, inc this month doesn't owe anything but you still want them to show up in the report they just won't have any child receivables.
The error is about
Illuminate/Events/Dispatcher
That's not an Eloquent model. You can't load relationships on classes that aren't Eloquent Models. Neither load() nor with() would work there, because those are relationship methods on Eloquent Models.
On your original post
get "Trying to get property 'categoryName' of non-object.
The reason why this worked
{{ $event->organizer->organizationName }}
and this didn't
{{ $event->categories->categoryName }}
is because organizer is a single model, so you can directly access properties. categories is a collection of many categories. You'd have to loop through them to get the category name for each category model that was returned in the categories property. It's an array, not a class.
Or do something like use the implode() collection method, to create a comma separated list
{{ $event->categories->implode('categoryName', ', ') }} // cat 1, cat 2, cat 3
@CRONIX - Hi Cronix!!
So if I was trying to understand why a relationship wasn't working how would I go about it? I tried $event->load('categories') and it shows null but in my database I can clearly see that an category with an id of 6 exists.
@CRONIX - But if I look at my relationships an event only belongsTo one category?
$event apparently isn't an eloquent model where you are using it. Illuminate/Events/Dispatcher proves that. It's an instance of a dispatchedEvent Listener. https://laravel.com/docs/5.7/events
Are you using Laravel events? Did you use the correct Event class? It would probably be better to not name your classes with the same classnames that laravel uses (like Event).
That issue with dispatcher was only happening in tinker. In my actual app it is working fine except for categories. When I tried
{{ dd($event->categories->implode('categoryName', ', ')) }}
in the blade file
I get
"Call to a member function implode() on null"
I didn't know that laravel had a class named event. That is probably a good call. Do you think it is worth going through the whole project and renaming?
Hi Chris
I'm used to Tinker auto-resolving the class name for models, but since your model is called Event, its getting it wrong
try
>>> $e = App\Event::with('categories')->find(14);
@SNAPEY - That worked in tinker! I got
App\Event {#2958
id: 14,
user_id: 11,
category_id: 9,
organizer_id: 11,
eventTitle: null,
slug: "468432130",
eventDescription: null,
eventWebsite: null,
eventPrice: null,
eventTicketUrl: null,
eventExpectations: null,
eventStreetNumber: null,
eventStreetAddress: null,
eventCity: "Cotati",
eventState: null,
eventCountry: null,
eventZipcode: null,
eventLong: null,
eventLat: null,
overallRating: "0",
eventImagePath: null,
thumbImagePath: null,
approved: 0,
visitors: 0,
created_at: "2019-03-13 22:25:09",
updated_at: "2019-03-14 17:20:19",
categories: null,
}
If I run
$e = Category::latest()->find(9);
I get
[!] Aliasing 'Category' to 'App\Category' for this Tinker session.
=> App\Category {#2962
id: 9,
event_id: null,
categoryName: "Fahey-Daugherty",
slug: "fahey-daugherty",
categoryDescription: "Architecto autem dolor esse maxime. Iure dignissimos id magnam quae dolorem sint sed deleniti. Et modi natus debitis voluptatum. Tempore soluta expedita ea nostrum eius.",
categoryImagePath: "category/992f662810a8c156a2971ea7d1a548ba.jpg",
created_at: "2019-03-12 00:25:28",
updated_at: "2019-03-12 00:25:28",
}
>>>
@cronix I bet that is what it is! What exactly do you mean by including local/foreign keys in the definition? Is that adding
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('organizer_id')->references('id')->on('organizers');
? Thanks
categories: null,
It still didn't get the categories though. Do you actually have categories assigned to that event?
Your tinker did not load the relationship, so its broken. FK's in your migration are not used when loading relations so you don't need to worry about them... thats a distraction.
Check the docs for what I mean about adding the keys to the relationships. No, it's not in the migration. It's in the relationship definition. https://laravel.com/docs/5.7/eloquent-relationships#one-to-many
Yeah as you can see,
Category_id: 9
and when I run
$e = Category::latest()->find(9);
I get
=> App\Category {#2962
id: 9,
event_id: null,
categoryName: "Fahey-Daugherty",
slug: "fahey-daugherty",
categoryDescription: "Architecto autem dolor esse maxime. Iure dignissimos id magnam quae dolorem sint sed deleniti. Et modi natus debitis voluptatum. Tempore soluta expedita ea nostrum eius.",
categoryImagePath: "category/992f662810a8c156a2971ea7d1a548ba.jpg",
created_at: "2019-03-12 00:25:28",
updated_at: "2019-03-12 00:25:28",
}
>>>
try it the other way, in tinker
$e = Category::with('events')->find(9);
Did this work? I see two events in there. Though this is exactly what I was trying to learn :) How to test for this stuff,
App\Category {#2953
id: 9,
event_id: null,
categoryName: "Fahey-Daugherty",
slug: "fahey-daugherty",
categoryDescription: "Architecto autem dolor esse maxime. Iure dignissimos id magnam quae dolorem sint sed deleniti. Et modi natus debitis voluptatum. Tempore soluta expedita ea nostrum eius.",
categoryImagePath: "category/992f662810a8c156a2971ea7d1a548ba.jpg",
created_at: "2019-03-12 00:25:28",
updated_at: "2019-03-12 00:25:28",
events: Illuminate\Database\Eloquent\Collection {#2977
all: [
App\Event {#2980
id: 9,
user_id: 9,
category_id: 9,
organizer_id: 9,
eventTitle: "Brakus-Watsica",
slug: "brakus-watsica",
eventDescription: "A saepe ex et a. Commodi sint harum quos unde hic minus aut. Id aut quia ratione.",
eventWebsite: "http://bode.com/quasi-voluptas-beatae-voluptas-reiciendis-itaque-dolor",
eventPrice: 3,
eventTicketUrl: "http://www.zemlak.org/",
eventExpectations: "Est et optio quo provident voluptas a non. Dolorem expedita sit voluptas omnis molestiae perferendis. Et adipisci et ea rerum quam vero.",
eventStreetNumber: "7",
eventStreetAddress: "8310 Littel Mountain",
eventCity: "Lake Kory",
eventState: "Massachusetts",
eventCountry: "Palestinian Territories",
eventZipcode: "45311-0754",
eventLong: "8",
eventLat: "6",
overallRating: "0",
eventImagePath: "event-images/97bca1d8c88f89e375ba0c4b4f77d253.jpg",
thumbImagePath: "thumb-images/bf68ef99ba799577b6a7026f4d8b3bfb.jpg",
approved: 0,
visitors: 5,
created_at: "2019-03-12 00:25:31",
updated_at: "2019-03-12 00:25:31",
},
App\Event {#2981
id: 14,
user_id: 11,
category_id: 9,
organizer_id: 11,
eventTitle: null,
slug: "468432130",
eventDescription: null,
eventWebsite: null,
eventPrice: null,
eventTicketUrl: null,
eventExpectations: null,
eventStreetNumber: null,
eventStreetAddress: null,
eventCity: "Cotati",
eventState: null,
eventCountry: null,
eventZipcode: null,
eventLong: null,
eventLat: null,
overallRating: "0",
eventImagePath: null,
thumbImagePath: null,
approved: 0,
visitors: 0,
created_at: "2019-03-13 22:25:09",
updated_at: "2019-03-14 17:20:19",
},
],
},
}
So that means maybe it is something to do with the relationship from events->category being confused with events->organizer.
In my category.php model I added
public function events()
{
return $this->hasMany(Event::class, 'category_id');
}
but still no luck. From what I read/understood on the docs I need to specify the key. Do I need to add foreign key as well?
Please or to participate in this conversation.