38

i have an array as follows

      'topic' => 
  array (
    'id' => 13,
    'title' => 'Macros',
    'content' => '<p>Macros. This is the updated content.</p>
',
    'created_at' => '2014-02-28 18:36:55',
    'updated_at' => '2014-05-14 16:42:14',
    'category_id' => '5',
    'tags' => 'tags',
    'referUrl' => '',
    'user_id' => 3,
    'videoUrl' => '',
    'useDefaultVideoOverlay' => 'true',
    'positive' => 0,
    'negative' => 1,
    'context' => 'macros',
    'viewcount' => 60,
    'deleted_at' => NULL,
  )

I would like to use this array and convert/cast it into the Topic Model . Is there a way this can be done.

thanks

7 Answers 7

43

For creating models from a single item array:

$Topic = new Topic();
$Topic->fill($array);

For creating a collection from an array of items:

$Topic::hydrate($result);
Sign up to request clarification or add additional context in comments.

3 Comments

also useful when updating a record from the database for instance: $model = \App\Models\TblTask::find(1); $model->fill($updatedTaskFields); $model->save();
Is there a ->fill(array $attributes) that's more particular for updating an existing model? btw, you might want to use ->findOrFail(int $id), that will throw an Exception if the ID is not found. Depends on your use-case though.
Ah, there is ->update(array $attributes = [], array $options = []), which does $this->fill($attributes)->save($options);
39

Try creating a new object and passing the array into the constructor

$topic = new Topic($array['topic']);

1 Comment

Second time in as many days , you have helped me . thanks once again ! :)
4

Here is a generic way to do it, not sure if there is a Laravel-specific method -- but this is pretty simple to implement.

You have your Topic class with its properties, and a constructor that will create a new Topic object and assign values to its properties based on an array of $data passed as a parameter.

class Topic
{

    public $id;
    public $title;

    public function __construct(array $data = array())
    {
        foreach($data as $key => $value) {
            $this->$key = $value;
        }
    }

}

Use it like this:

$Topic = new Topic(array(
    'id' => 13,
    'title' => 'Marcos',
));

Output:

object(Topic)#1 (2) {
  ["id"]=>
  int(13)
  ["title"]=>
  string(6) "Marcos"
}

1 Comment

Just checked the documentation, as long as your class extends Eloquent, you can use @TheShiftExchange's answer. My example pretty much shows what his answer does.
2

It seems that you have data of an existing model there, so:

  1. First, you can use that array to fill only fillable (or not guarded) properties on your model. Mind that if there is no fillable or guarded array on the Topic model you'll get MassAssignmentException.
  2. Then manually assign the rest of the properties if needed.
  3. Finally use newInstance with 2nd param set to true to let Eloquent know it's existing model, not instantiate a new object as it would, again, throw an exception upon saving (due to unique indexes constraints, primary key for a start).

.

$topic = with(new Topic)->newInstance($yourArray, true);
$topic->someProperty = $array['someProperty']; // do that for each attribute that is not fillable (or guarded)
...
$topic->save();

To sum up, it's cumbersome and probably you shouldn't be doing that at all, so the question is: Why you'd like to do that anyway?

7 Comments

@deczo.. I am working with queues . ideally I would like to pass the model to the queue, but when I pass the model to the queue , its not working. when I am passing it as an array everything works
I think serializing is the way to go with that. Model utilizes magic method __wakeup for unserializing, what would do the job for you. Not sure how serialized object is going to work with queues though. And mind that new Topic($array) is not going to work as expected, like stated in my answer.
Well , I know what you meant as soon as i tried the code. You are right the id is getting populated , but the isdirty is false which means that the update is going to fail. but i will have to follow your second approach then.. to manually populate the properties which will be a huge pain because of the risk missing of some properties when newer ones are implemented.
Yes, it will be a pain in the very well known place ;) I highly suggest examining possibility of serializing it instead.
Can you please pass me some more information regarding this __wakeup please. It seems i cannot find anything related to this . Must be my inability to read the laravel docs. thanks
|
1

Look at these two available methods in L5 newInstance and newFromBuilder

e.g with(new static)->newInstance( $attributes , true ) ;

Comments

0

I would likely create the new instance of the object and then build it that way, then you can actually split some useful reusable things or defaults into the model otherwise what's the point in pushing an array into a model and doing nothing with it - very little besides for normalization.

What I mean is:

$topic = new Topic();
$topic->id = 3489;
$topic->name = 'Test';

And the model would simply be a class with public $id;. You can also set defaults so if you had like resync_topic or whatever property, you can set it as 0 in the model rather than setting 0 in your array.

Comments

0

I came across this question looking for something else. Noticed it was a bit outdated and I have another way that I go about handling the OPs issue. This might be a known way of handling the creation of a model from an array with more recent versions of Laravel.

I add a generic constructor to my class/model

public function __construct(array $attributes = [])
{
    parent::__construct($attributes);
}

Then when I want to create a new instance of the model from an array I make a call like this

$topic = new Topic($attrs);
// Then save it if applicable
$topic->save(); // or $topic->saveOrFail();

I hope someone finds this helpful.

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.