0

I have a Model method where I am trying to return a start and end date.

So like this:

public function start_end_date()
    {

        $instances = $this->hasMany(Instance::class, 'instance_id')
            ->where('instance_id', '=', $this->id)
            ->where('weekstart', '>=', time());

        $dates = $instances->pluck('weekstart')->toArray();
        $dates = array_map('strtotime', $dates);
        $startdate = min($dates);
        $enddate = strtotime("+7 day", max($dates));

        return array('startdate' => $startdate, 'enddate' => $enddate);
    }

In my view, I have $courses passed to the view. This object returns courseinstances via its model, as

 public function courseinstances()
    {

        return $this->hasMany(CcoursesInstance::class, 'course_id')
            ->where('startdate', '>=', time());
    }

So in view I can loop over $courses (e.g. @foreach $courses as $course) and also loop over instances (e.g. @foreach $course->courseinstances as @instance) and that works fine. For instance I can access some field or method-returned value as $instance->somedata

But in the view where I have $course->courseinstances->start_end_date->startdate

Laravel says

Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation (View:

I just can't figure out how Laravel wants me to return the start and end date and then reference it in the view. I don't want to pass separate variables to the view. I want to just use $courses as passed to the view and then drill down as I do for other pieces of data related to a course.

Ideas?

Thanks, Brian

2 Answers 2

1

start_end_date is not a property, it's a method so you need to declare it as a property, also $instances is returning a query builder instance and not a collection that you can pluck from, so append get() to actually retreive records

public function getStartEndDateAttribute()
{
    $instances = $this->hasMany(Instance::class, 'instance_id')
                      ->where('instance_id', '=', $this->id)
                      ->where('weekstart', '>=', time())->get();
}
Sign up to request clarification or add additional context in comments.

5 Comments

Without using get() the code still works (maybe because I am on Laravel 5.3). But just not sure syntax of the return statement that is needed and what referencing syntax I need to use in the view. Just read here laravel.com/docs/5.3/eloquent-mutators about Mutators, but seems to assume that you are referencing a column name. In my case, there is no column name, as I am generating the start and end date on the fly.
This is an accessor and doesn't relate to a column name, mutators begins with set instead of get
In the Laravel 5.3 doc, it says "To define an accessor, create a getFooAttribute method on your model where Foo is the "studly" cased name of the column you wish to access" If I use function name getStart_end_dateAttribute(), and in view use $instance->start_end_date['startdate'], the method is not being called.
Ok, have it figured out. Needed to rename function getStartEndDateAttribute() - thanks for helping me get this figured out!
The more I use this approach, the more I realize it is flawed, because on my backend I have angular controllers. Seems for these custom attributes to work in angular I need to use protected appends and that causes weird behavior (like the get attribute method being called when it shouldn't. So now I am back full circle and wondering how I could make a start_end_date() model method return the form of data needed so that in blade or angular controller I can access as $instance->start_end_date or in angular instance.start_end_date
0

It's an array so you should get the value via it's array index like so:

$course->courseinstances->start_end_date['startdate']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.