Converting Laravel-4 Eloquent query results to arrays - laravel

I'm trying to get my route to insert a new row into the database, and if successful return the record (with its new primary key id) in some JSON. I'm getting the following error:
{
"error":
{
"type":"BadMethodCallException",
"message":"Call to undefined method Illuminate\\Database\\Query\\Builder::to_array()",
"file":"\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Query\\Builder.php",
"line":1418
}
}
This is my route:
Route::post('/client/create', function()
{
$client = Client::create(Input::all());
if($client)
{
return json_encode(array('Result' => 'OK', 'Record' => $client->to_array()));
}
else
{
return json_encode(array('Result' => 'ERROR', 'Message' => 'Error Inserting Record =('));
}
});
According to the Laravel docs I've read, you're supposed to use ->to_array() to convert your model to an array, and ::create returns an instance of the model if successfully inserted. I've checked the database, and the records are being inserted just fine.

By default if you were to return an Eloquent model directly it would convert the model to it's JSON representation. This is because the __toString magic method on each model returns the model as JSON by using the toJson method.
As such the model implements both the ArrayableInterface and JsonableInterface. That means you can directly call toJson or toArray on a model.
Now you can mark columns as hidden. This means that when a model is converted into it's array or JSON representation some columns are removed (think publicly accessible API, you don't want passwords showing up!). I'm not totally sure but maybe the ID of your model is being hidden.
At the end of the day, all you need to do is return the instance.
return $client;
It'll be converted to JSON for you automatically.

The to_array() method comes from Laravel 3. Use toArray() in Laravel 4.

I see question similar you try to return data to jquery jtable and same me
Player::orderBy($sort)->paginate($pagesize)->getCollection();
return Response::view(array('Result'=>'OK','Records'=>$player->toArray()));
for try many hour I found solution getcollection pull instance from object and then solve

Related

Laravel: retrieving one item from a relationship

I am using Laravel Eloquent to retrieve data from the database.
I want to get the related data as an object not an array ( whats inside the texts table), so it is easier to work on the data on the blade file. This is my code I tried using first() but it doesn't work
Icon::with(["texts" => function($query) use ($language){
$query->where("language_id",$language->id)->first();
}, "texts.language"])->get();
How to Acheive it?
You could create an accessor function that provides a shorthand attribute to the required value.
In your Icon class:
public function getTextAttribute() {
// You'd only have to provide the $language somehow.
return $this->texts()->where('language_id', $language->id)->first();
}
Elsewhere, like in Blade, when you're using an Icon you can then use:
{{$icon->text}}

Fetching all database entries with their relationships using a Resource

So, I'm currently trying to fetch every entry from one database table and returning them using an APIResource. I wanna also return every relationship of those entries.
Here is my controller:
public function all()
{
return GameResource::collection(Game::all()->with('white_user', 'black_user', 'win_user')->get());
}
And the corresponding Resource:
public function toArray($request)
{
return [
'GmID' => $this->GmID,
'White_user' => new UserPublicResource($this->whenLoaded('white_user')),
'Black_user' => new UserPublicResource($this->whenLoaded('black_user')),
'Winner' => new UserPublicResource($this->whenLoaded('win_user')),
'Pgn' => $this->Pgn,
'StartTime' => $this->StartTime
];
}
I am aware that the Problem lies in the all() method which returns a collection which doesnt have a with() method.
Here is the error message:
Method Illuminate\Database\Eloquent\Collection::with does not exist.
I am wondering if there is an easy way to do what I want to and I can't seem to find anything in the docs or anyone on the internet who wanted something similar.
you are calling with after fetching data which is collection and collection don't have with method call this way will work it will fetch all data from game table.
return GameResource::collection(Game::with('white_user', 'black_user', 'win_user')->get());

Eloquent - edit table rows and return new result data - old data retrieved

I have a form where the user can edit, create or delete shipping methods.
The user sends the form and the data is updated.
I want to return the user's shipping methods after they are edited.
But I seem to get the old data back, instead of the updated data.
$user = \App\User::where('user_id', $user->id)->first();
$user->shipping_methods->each(function($method) {
$method->delete();
});
$methods = [];
foreach ($request->input('methods') as $method) {
$methods[] = new \App\ShippingMethod($method);
}
$user->shipping_methods()->saveMany($methods);
return response()->json($user->shipping_methods->toArray());
(at the moment the code just deletes the old shipping methods and replaces them with the new ones). I am using eloquent relations to get the shipping methods.
So when I do:
return response()->json($user->shipping_methods->toArray());
how come I don't get the new results, instead I get the results from before the update? Is it using the results from the first $user->shipping_methods at line 3? Should I "refresh" the query somehow?
You have to reload the relationship:
return response()->json($user->load('shipping_methods')->shipping_methods->toArray());
You can also simplify the whole line:
return $user->load('shipping_methods')->shipping_methods;
The saveMany method of \Illuminate\Database\Eloquent\Relations\HasMany return instace of \Illuminate\Database\Eloquent\Collection and you must manually set relations
$shipping_methods = $user->shipping_methods()->saveMany($methods);
$user->setRelation('shipping_methods', $shipping_methods);
return response()->json($user->shipping_methods->toArray());

associate() and 1tomany strange behavior

im using Laravel 5.3 and ive a simple controller with a "store" method, this is the "belongTo" side of the relations.
The others 2 models contain correctly the "hasMany" function.
public function store(Request $request)
{
$user_id = JWTAuth::parseToken()->authenticate()->id;
if(!Vehicle::where('id', '=', $request->vehicle_id)->exists()){
return $this->response->error('could_not_create_trip_errore_veicolo', 500);
}
if(!Ztl::where('id', '=', $request->ztl_id)->exists()){
return $this->response->error('could_not_create_trip_errore_ztl', 500);
}
$request->request->add(['user_id' => $user_id]);
$trip = new Trip($request->all());
//$trip->user()->associate($request->user_id);
//$trip->vehicle()->associate($request->vehicle_id);
//$trip->ztl()->associate($request->ztl_id);
if(true)
{
if($trip->save()){
return $this->response->created();
}else return $this->response->error('could_not_create_trip', 500);
}else return $this->response->error('could_not_create_trip_current_user_Error', 500);
}
First question is:
why if comment or uncomment the "associate" method, nothing changes.
Do I need to put these on the controller or I've not weel understand what is the meaning of this method.
Second:
If I send to my controller some data, using form for testing, what is "required" is the 3 foreign keys.
If I send a number that is not on my other "hasmany" table an error is rise, but if try to insert something like "2dsksk" where 2 is a correct ID of the "many" table and then a random string, the ID is taken by the insert as 2, this is correct?
Validation take just the "correct" number part of the data...the question is, why? and this is secure?
associate just sets the foreign key of the child. This means you will need to save your model afterwards.
$trip->user()->associate($request->user_id);
$trip->save();
For the second issue, that's likely MySQL truncating the data based on the data type of the column. If you don't want that to happen, you would likely need to set MySQL to strict mode.
http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-strict

Attaching new relation and returning the model

I have a User that has many Positions. I want to update the User (the model and the relation Position), and then return the updated result.
The input will be an array of the format
{
first_name,
last_name,
email,
... (other user information),
positions : [
{
id,
name,
descriton
},
...
]
}
My update function currently is
public function update($id)
{
// This is a validation that works fine
if ( ! User::isValid(Input::all())) return $this->withValidation(User::$errors);
$user = User::with('positions')->find($id);
$new_ids = array_pluck(Input::get('positions'), 'id');
$user->positions()->sync($new_ids);
$user->update(Input::all());
return $user;
}
My User and its permissions are updated, but I still get the old $user's relationship back (i.e. the basic information is updated, and the new positions are updated in the DB, but the returned result is the NEW basic information with the OLD positions).
Right now to fix this, I recall the User::with('positions')->find($id) at the end and return that. But why isn't my code above working?
Correct, sync doesn't update related collection on the parent model.
However you should use $user->load('positions') to reload the relation, it will call only 1 query, without fetching the user again.
Also, you can call load on the Collection:
$user->positions->load('anotherRelation');
because here positions is a Collection, which have load method to lazy load all the related models for each item in the collection.
This would not work, since positions() returns relation object, not collection:
$user->positions()->load('anotherRelation');

Resources