Laravel 5 - Updating associated models using push() - php

I am trying to do this:
$volunteer = Volunteer::with('user')->find($id);
$input = $updateVolunteerRequest->all();
$volunteer->fill($this->fillFields($input));
$volunteer->user->fill([
'email' => $input['email']
]);
$volunteer->push();
But push() method does not seem to work.
It throws the following error:
FatalErrorException in Model.php line 1463:
Call to a member function push() on a non-object
It worked in Laravel 4. Is there a new way of doing this in version 5? Or am I doing something wrong.
I checked $volunteer and it returns the model.

The push method loops through all of the loaded relationships on the model and calls push on them, as well. So, it isn't the push on the $volunteer that's failing, it is a push on a related model that is failing.
In Laravel 4, push has the following code:
foreach ($this->relations as $models)
{
foreach (Collection::make($models) as $model)
{
if ( ! $model->push()) return false;
}
}
In this code, if the relationship returned a NULL, there would be no error. Collection::make(NULL) returns an empty array, so the foreach would never execute. However, in Laravel 5, push has this code:
foreach ($this->relations as $models)
{
$models = is_array($models) ? $models : array($models);
foreach ($models as $model)
{
if ( ! $model->push()) return false;
}
}
In this case, if the relationship is null, there will be an error, since array(NULL) returns an array with one entry: the NULL value. So, the foreach loop will execute, and it will try to call push on the NULL value, resulting in your Call to a member function push() on a non-object error.
So, it looks like this is a bug in Laravel 5.
Edit
It looks like the push() method was updated because of an update made to the Collection object. I have submitted a pull request to correct the issue. You can check out the pull request here, which also contains links to reported issues and other background information.
Edit 2
My pull request was merged in, so you should be able to update your Laravel 5 to the newest version and the issue should be corrected.

Related

Not able to call SAVE method on Model object Laravel

I'm trying to call save method on an object of a Model Complaints Model to update a specific resource in Database but when I send a POST request on api url it gives this error
BadMethodCallException: Method Illuminate\Database\Eloquent\Collection::save does not exist.
I also tried calling update method but same error.
Code for edit:
$complaint = Complaint::where('complaint_id', $request->input('id'))->get();
$complaint->title = $request->input('Complaint_Subject');
$complaint->description = $request->input('Complaint_Details');
$complaint->address = $request->input('Complaint_Address');
$complaint->update();
return [
'save_status' => "success"
];
the very first line is returning the response and correct response.
AND
also I'm trying to call delete or destroy method to delete the resource but it also gives the same error
BadMethodCallException: Method Illuminate\Database\Eloquent\Collection::delete does not exist.
or
BadMethodCallException: Method Illuminate\Database\Eloquent\Collection::destroy does not exist.
Code for delete:
$complaint = Complaint::where('complaint_id', $request->input('id'))->get();
$complaint->destroy($request->input('id'));
return [
'request_status' => 'success',
'complaint' => $complaint
];
here also the response is being returned correctly.
Note that the complaint_id is not Primary Key in the table so I cannot simply call Complaint::find($request->input('id')) I must have to cross check with this complaint_id column value to find the resource. I have been searching since yesterday but could not find any solution. How can I solve this problem. Thanks!!!
If your $complaint is a collection of output. So save didn't work for this if you change your code like $complaint = Complaint::where('complaint_id', $request->input('id'))->first(); Then save() will work.
just use first() instead of get()
Complaint::where('complaint_id', $request->id)->first()
In your query
$complaint = Complaint::where('complaint_id', $request->input('id'))->get();
it returns Associative Arrays
But if you use
$complaint = Complaint::where('complaint_id', $request->input('id'))->first();
it returns Indexed or Numeric Arrays. Then you have to use $complaint[0]->destroy($request->input('id')); or $complaint[1]->destroy($request->input('id')); and so one

Laravel dynamic queries on array of Eloquent models

I am currently trying to make a function that calls different scopeQueries such as scopeByLocation() or scopeByPublished() on models defined in an array. I've got the basics working through [this link][1]. However, when trying to access custom made query scopes that are defined in the corresponding model, I get the following error: "Call to undefined method Illuminate\Database\Query\Builder::ForLocation($location)->get()".
What I want to achieve is a single method which loops through every model in the array of models and retrieves & calls the right scopeQuery on the model, something like this:
$modelElements = $model::{$queryScope}();
Where for example $model = 'Modules\News\Models\Article'
And $queryScope is a defined queryScope in the model itself. E.g. scopeForLocation($location).
I've tested $queryScope = 'all' and I get a result just fine, however when I try to access a custom queryScope ($queryScope = 'ForLocation($location)->get') that exists within for example the Location model, I get the following error: "Call to undefined method Illuminate\Database\Query\Builder::ForLocation($location)->get()".
So this all happens in a foreach-loop where every model in my models-array gets called and then the corresponding queryScope gets called on the model.
Why does the $queryScope = 'all' method works on my dynamic models, but other scopes throw an error? I really hope someone could help me get into the right direction with this issue.
Thanks in advance,
J. Doe.
Okay, I've finally solved it the following way:
//array of models
public function models()
{
return [
'Modules\Website\Models\Article',
...
];
}
//function that retrieves all elements for a model
public function getAllElementsForModel($model, $param)
{
//instantiate model
$model = new $model;
//call queryScope
//'queryScope' could be any queryScope that is defined within your model(s),
//the parameters are needed for the associated queryScope
$query = call_user_func_array([$model, 'queryScope'], [$param1, $param2]);
$result = $query->get();
//do stuff with your $result
}
//retrieves all
public function all($param)
{
//loop through the array of models
foreach($this->models() as $model){
$this->getAllElementsForModel($model, $param);
//do stuff here...
}
}
Sharing is caring!

Add items to paginator laravel 4

So i have a problem when i want to add element to Paginator collection, i got this error :
call_user_func_array() expects parameter 1 to be a valid callback, class 'Illuminate\Support\Collection' does not have a method 'add'
This is my code :
$data = $users->whereBetween('program_date',[$from,$to . ' 23:59:59'])->paginate(10);
$tests = $test->whereBetween('created_at',[$from,$to . ' 23:59:59'])->paginate(10);
foreach ($tests as $sms) {
$camp = new Campagne();
$camp->user_id = $sms->user_id;
$data->add($camp); // i got error in this line!!
}
so please if someone has any idea how to use ->add($element) with laravel pagination i will be very appreciative.
I don't think Collection has a function called add. also I am not sure you can loop through, at least not the models, with straight from Paginator. I believe you need to change it to
foreach( $tests->getItems() as $sms ){
.....
}
the reason it won't work this way is when you paginate a collection you get an instance of Illuminate\Pagination\Paginator class and when you loop through, you are basically looping class object not your items.

Zend Framework 2 Update Value of ResultSet Object

Zend framework 2 newb here so bear with me. See the code below:
public function setMediaToTrue($users) {
foreach($users as $user) {
$user->media = true;
}
return $users;
}
This method receive $users ResultSet object and update the media property to true. The problem is I can't modify the property of $users object inside iteration. Things that I have tried :
1. Use $users->current() inside iteration. example below :
$users->current()->media = true;
Create setMedia inside $user model and use it inside iteration:
$user->setMedia(true); // This does not update the property either
I think the problem because ZF2 create new copy of object for each iteration. I was looking at using Hydrator but can't get my head around it.
Thanks

Fatal error: Call to a member function create() on a non-object in <file>

For a php project I use a Collection class to handle my objects and lazyloading in Java-like collections.
Now my object has a collection of emailaddresses for example. So I call the getEmailAddresses() function of the object which calls the mapper to return a collection of emailaddresses.
This works fine, but when I do a foreach loop over my collection it returns valid data with the following error in the end:
Fatal error: Call to a member function create() on a non-object in /foo/bar/Collection.php on line 89
It directs to the following function:
public function current()
{
if ($this->_collection instanceof Iterator)
$key = $this->_collection->key();
else
$key = key($this->_collection);
if ($key === null)
return false;
$item = $this->_collection[$key];
if (!is_object($item)) {
$item = $this->_gateway->create($item);
$this->_collection[$key] = $item;
}
return $item;
}
This line:
$item = $this->_gateway->create($item);
The _gateway is the adapter the collection uses. Which I don't use and keep it null. Maybe it has something to do with that?
Anybody has some clue? Because everything is functioning as it should, I can read the collectiondata. It's just the error.
Replace
if (!is_object($item))
with
if (!is_object($item) && !is_null($this->_gateway))
This of course only makes sure the code doesn't get called if gateway isn't set, so it doesn't do anything to $item (which might not be what you want).
Already got it!
It appears that if the collection requested doesnt have any objects, it just tries to do something.
If I first count the items and compare it to > 0 it doesnt return any errors. This is going to be an issue so I'll update the class to check for it first.
I'm not the only one working with it, this is not an error you would expect.
This only means that $this->_gateway is not an object and it should be. It can't be null.
You can change this line:
$item = $this->_gateway->create($item);
to
if(is_object($this->_gateway)) {
$item = $this->_gateway->create($item);
}
this will fix this error, but can lead to more errors further down, depending on what exactly is $item supposed to be.

Categories