laravel problems with mutators
Asked Answered
R

1

3

My journey into laravel 4 (from laravel 3) continues....

I have an Article model, accessing a table called articles.

I have set up the model with the following mutators:

class Article extends Eloquent {

 public function getArticleDateAttribute($value)
{
    return date('d/m/Y', strtotime($value));
}

public function getValidUntilAttribute($value)
{
    return date('d/m/Y', strtotime($value));
}

}

Now when I query the database with the following AND Delete the mutators everything works as expected and I get the data I expect:

public function getTest() {

    $data = Article::select(array(
        'articles.id',
        'articles.article_date',
        'articles.image_link',
        'articles.headline',
        'articles.category'
    ))  ->get()
        ->toArray();
    var_dump($data);
    //return View::make('_layouts.master');
}

In my test I get the results as expected as this sample:

array (size=5)
  'id' => int 3
  'article_date' => string '2008-06-03 00:00:00' (length=19)
  'image_link' => string '' (length=0)
  'headline' => string 'Sussex Amateur Course Closure' (length=29)
  'category' => int 6

Now, when I add back the mutators, with the exact query I get the following data:

array (size=6)
  'article_date' => string '03/06/2008' (length=10)
  'valid_until' => string '01/01/1970' (length=10)
  'id' => int 3
  'image_link' => string '' (length=0)
  'headline' => string 'Sussex Amateur Course Closure' (length=29)
  'category' => int 6

the column order is changed and it's included a column I didn't originally request. How should I correctly implement mutators and why do the columns change?

Have I misunderstood this?

Thanks

Ray

Rigorism answered 7/6, 2013 at 13:44 Comment(2)
It looks like a bug inside Eloquent\Model. Why can't You pass collection (not an array) to view?Philologian
Hi. I'm eventually passing the data to a datatables plug in - and will be using an object. However the same corruption occurs (of adding in the valid_until attribute. Passing to an array for testing purposes only for now so I can see the results. These results though do mirror those in the object (order and column order etc). I wasnt expecting thye column re-ordering or additional column - didnt happen in L3Rigorism
M
0

The mutators will be called, because the code is built that way. See the implementation of this function in the Eloquent Model class (which is called by toArray()):

/**
 * Convert the model's attributes to an array.
 *
 * @return array
 */
public function attributesToArray()
{
    $attributes = $this->getAccessibleAttributes();

    // We want to spin through all the mutated attributes for this model and call
    // the mutator for the attribute. We cache off every mutated attributes so
    // we don't have to constantly check on attributes that actually change.
    foreach ($this->getMutatedAttributes() as $key)
    {
        if ( ! array_key_exists($key, $attributes)) continue;

        $attributes[$key] = $this->mutateAttribute($key, $attributes[$key]);
    }

    return $attributes;
}

https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Eloquent/Model.php

Mirna answered 7/6, 2013 at 16:50 Comment(2)
When I has this in L3 I only got the columns/fields that were included in the select. So - with this function in place, every time I call from this model I'll get the additional columns whether I want them or not? I thought it only modified and returned the data if it existed in the query?Rigorism
I think you are right and the code is not doing what it should be doing. You should open an issue on Github to discuss this I guess.Mirna

© 2022 - 2024 — McMap. All rights reserved.