Laravel dates on model binding

I am using Laravel 5.1

I have a model:

class ExampleModel extends Model {

    // ....
    protected $dateFormat = 'Y.m.d';
    protected $dates = ['first_date', 'second_date'];

    // ...
}

      

So when I index the elements of the ExampleModel the date format is correct (ex 2015.07.31)

But in the edit form, it uses the default format: 2015-07-31 00:00:00

I am using anchor Form::model()

.

I know I can use it getFirstDateAttribute()

, but this is not the solution I am looking for. Since it is not elegant at all, and once I have defined an array $dates

, it should work automatically in every case.

So maybe this is a mistake? Or am I doing something wrong?

+3


source to share


3 answers


I've never done this before, but it seems to work with a basic example I put together. Note that I am just calling a method toArray

on the model in the form open tag.

{!! Form::model($exampleModel->toArray(), ['route' => ['example-models.update', $exampleModel->id]]) !!}
    {!! Form::label('first_date', 'First Date') !!}
    {!! Form::text('first_date') !!}
{!! Form::close() !!}

      



The docs say the property dateFormat

defines the date format when the object is passed to json or array.

+1


source


I solved my problem by overriding Carbon's default date format:

Carbon\Carbon::setToStringFormat('Y.m.d');

      



But Kelly's answer is much better and more elegant, I'll just post it, maybe someone will find it useful once.

+3


source


I do not fully recommend this as a fix, because when you update your kernel you will lose this fix, but perhaps this should be posted as a pull request to the next Laravel version.

In \ Illuminate \ Database \ Eloquent \ Concerns \ HasAttributes updates the asDate function as follows. As you can see from the comments, the asDate function still returns the timestamp even if it's 00:00:00.

/**
     * Return a timestamp as DateTime object with time set to 00:00:00.
     *
     * @param  mixed  $value
     * @return \Illuminate\Support\Carbon
     */
    protected function asDate($value)
    {
        $date = $this->asDateTime($value)->startOfDay();
        $date->setToStringFormat($this->getDateFormat());
        return $date;
    }

      

This allows you to control the format of the date from the model (note that I differentiate between date and date and time). Then use the casts variable to convert your variable to date format.

protected $casts = [
    'start_date' => 'date',
    'end_date' => 'date'
  ];
  protected $dateFormat =  'Y-m-d';

      

The variable $ date cannot distinguish between date and date and time.

UPDATE The real problem is that binding to the model form is missing the FormBuilder class helper function. As you can see if you are checking \ Collective \ Html \ FormBuilder :: date

/**
 * Create a date input field.
 *
 * @param  string $name
 * @param  string $value
 * @param  array  $options
 *
 * @return \Illuminate\Support\HtmlString
 */
public function date($name, $value = null, $options = [])
{
    if ($value instanceof DateTime) {
        $value = $value->format('Y-m-d');
    }

    return $this->input('date', $name, $value, $options);
}

      

Formats the date correctly before 'Ym-d' as stated in the HTML5 spec. However, at this point, the value of $ is effectively null. Therefore, you need to update the general input function.

/**
 * Create a form input field.
 *
 * @param  string $type
 * @param  string $name
 * @param  string $value
 * @param  array  $options
 *
 * @return \Illuminate\Support\HtmlString
 */
public function input($type, $name, $value = null, $options = [])
{
    ...

    //$value is null here
    if (! in_array($type, $this->skipValueTypes)) {

        //$value is fetched based on hierarchy set by
        $value = $this->getValueAttribute($name, $value);

        //necessary duplicate code to format date value
        if ($type == 'date' && $value instanceof DateTime) {
            $value = $value->format('Y-m-d');
        }
    }

    ...
}

      

UPDATE No need to update vendor code. Check FormModelAccessors

https://laravelcollective.com/docs/5.2/html#form-model-binding

0


source







All Articles