if I have an Eloquent Model called Post, and the mysql table has:
integer ID,
string Text
How do I convert this JSon:
{ post: { text: 'my text' } }
To the relevant Post object that, once received in the controller, I can save to the database like this:
public function store(Post $post)
{
$post->save();
}
I'm not looking to build the logic that would do that for me, but for the Laravel way (or could it be that there isn't one? I googled it with no relevant results).
Convert json to array
Hydrate model from array
$data = '{
"unique_id_001":{"name":"John","email":"JD#stackoverflow.com"},
"unique_id_002":{"name":"Ken","email":"Ken#stackoverflow.com"}
}';
$object = (array)json_decode($data);
$collection = \App\User::hydrate($object);
$collection = $collection->flatten(); // get rid of unique_id_XXX
/*
Collection {#236 ▼
#items: array:2 [▼
0 => User {#239 ▶}
1 => User {#240 ▶}
]
}
*/
dd($collection);
fill looks like the method you want. To avoid adding every attribute to your $filled array, which you would need to do if you wanted to use the fill method, you can use the forceFill method.
It accepts an associative array of attributes, so the JSON will have to be decoded, and we'll have to get the inner post key:
$rawJson = "{ post: { text: 'my text' } }";
$decodedAsArray = json_decode($rawJson, true);
$innerPost = $decodedAsArray['post'];
Once we have the decoded data, we can create an instance of the Post eloquent model and call forceFill on it:
$post = new Post();
$post->forceFill($innerPost);
$post->save();
This is similar to doing:
$post = new Post();
foreach ($innerPost as $key => $value) {
$post->$key = $value;
}
$post->save();
Just turn it to array and fill an eloquent
$arr = json_decode($json, true);
$post = new Post;
$post->fill($arr);
It's way simple as like followings:
$json_post = { "post": { "text": "my text" } };
$post = new Post(
json_decode($json_post, true)
);
Now, you can run all eloquent methods on the most $post, ex:
$post->save()
I tested with laravel v7.11.0
Can you try it like this?
public function store($poststuff)
{
$post = new Post;
$post->text = $poststuff['text'];
$post->save();
}
Related
I have some of the data, I want to save my data-id in array format. How can I do this? Below is my controller code.
Controller:
public function PostSaveRentCertificateReport(Request $request)
{
$report = $request->session()->get('report');
$reports = new Report;
$reports->column_one = $report->sum('column_one');
$reports->column_two = $report->sum('column_two');
// I want to save those id as array
$reports->adc_report_id = array('$report->id');
$reports->save();
$notification = array(
'message' => 'Report Created Successfully',
'alert-type' => 'success'
);
return redirect()->route('adc.pending.reports')->with($notification);
}
You can encode the data as JSON before saving it.
$reports = new Report;
$reports->column_one = $report->sum('column_one');
$reports->column_two = $report->sum('column_two');
$reports->adc_report_id = json_encode([$report->id]);
$reports->save();
But this will make it a bit more difficult to work with.
I am trying to pass $request from a function in controller to a function in model.
THis is my controller function:
PostController.php
public function store(Request $request, post $post)
{
$post->title = $request->title;
$post->description = $request->description;
$post->save();
return redirect(route('post.index'));
}
how save data in model Post.php?
I want the controller to only be in the role of sending information. Information is sent to the model. All calculations and storage are performed in the model
Thanks
You can make it even easier. Laravel has it's own helper "request()", which can be called anywhere in your code.
So, generally, you can do this:
PostController.php
public function store()
{
$post_model = new Post;
// for queries it's better to use transactions to handle errors
\DB::beginTransaction();
try {
$post_model->postStore();
\DB::commit(); // if there was no errors, your query will be executed
} catch (\Exception $e) {
\DB::rollback(); // either it won't execute any statements and rollback your database to previous state
abort(500);
}
// you don't need any if statements anymore. If you're here, it means all data has been saved successfully
return redirect(route('post.index'));
}
Post.php
public function postStore()
{
$request = request(); //save helper result to variable, so it can be reused
$this->title = $request->title;
$this->description = $request->description;
$this->save();
}
I'll show you full best practice example for update and create:
web.php
Route::post('store/post/{post?}', 'PostController#post')->name('post.store');
yourform.blade.php - can be used for update and create
<form action='{{ route('post.store', ['post' => $post->id ?? null]))'>
<!-- some inputs here -->
<!-- some inputs here -->
</form>
PostController.php
public function update(Post $post) {
// $post - if you sent null, in this variable will be 'new Post' result
// either laravel will try to find id you provided in your view, like Post::findOrFail(1). Of course, if it can't, it'll abort(404)
// then you can call your method postStore and it'll update or create for your new post.
// anyway, I'd recommend you to do next
\DB::beginTransaction();
try {
$post->fill(request()->all())->save();
\DB::commit();
} catch (\Exception $e) {
\DB::rollback();
abort(500);
}
return redirect(route('post.index'));
}
Based on description, not sure what you want exactly but assuming you want a clean controller and model . Here is one way
Model - Post
class Post {
$fillable = array(
'title', 'description'
);
}
PostController
class PostController extend Controller {
// store function normally don't get Casted Objects as `Post`
function store(\Request $request) {
$parameters = $request->all(); // get all your request data as an array
$post = \Post::create($parameters); // create method expect an array of fields mentioned in $fillable and returns a save dinstance
// OR
$post = new \Post();
$post->fill($parameters);
}
}
I hope it helps
You need to create new model simply by instantiating it:
$post = new Post; //Post is your model
then put content in record
$post->title = $request->title;
$post->description = $request->description;
and finally save it to db later:
$post->save();
To save all data in model using create method.You need to setup Mass Assignments when using create and set columns in fillable property in model.
protected $fillable = [ 'title', 'description' ];
and then call this with input
$post = Post::create([ 'parametername' => 'parametervalue' ]);
and if request has unwanted entries like token then us except on request before passing.
$post = Post::create([ $request->except(['_token']) ]);
Hope this helps.
I find to answer my question :
pass $request to my_method in model Post.php :
PostController.php:
public function store(Request $request)
{
$post_model = new Post;
$saved = $post_model->postStore($request);
//$saved = response of my_method in model
if($saved){
return redirect(route('post.index'));
}
}
and save data in the model :
Post.php
we can return instance or boolean to the controller .
I returned bool (save method response) to controller :
public function postStore($request)
{
$this->title = $request->title;
$this->description = $request->description;
$saved = $this->save();
//save method response bool
return $saved;
}
in this way, all calculations and storage are performed in the model (best way to save data in MVC)
public function store(Request $request)
{
$book = new Song();
$book->title = $request['title'];
$book->artist = $request['artist'];
$book->rating = $request['rating'];
$book->album_id = $request['album_id'];
$result= $book->save();
}
The following method is intended to return an array with another array, 'data' and an Object (The result of some eloquent query).
It is however returning an array with two objects in it; $data is somehow being converted to an object with multiple child-objects, rather than being an array of objects. It should be noted that a dd($data) before the return statement reveals that it is indeed an array of objects. I think that somehow the Laravel middleware that handles response is returning this as an object instead...
Any idea how to work around this?
public function getTestData($id) {
$participants = Participant::where('test_id', $id)->with('testRecords')->get();
$finalRecordValue = TestRecord::where('test_id', $id)->orderBy('created_at', 'desc')->first();
$data = [];
foreach ($participants as $participant) {
foreach ($participant->testRecords as $testRecord) {
if (!array_key_exists((int)$testRecord->capture_timestamp, $data)) {
$data[$testRecord->capture_timestamp] = (object)[
'category' => $testRecord->capture_timestamp,
'value' . "_" . $participant->id => $testRecord->score
];
} else {
$data[$testRecord->capture_timestamp]->{"value" . "_" . $participant->id} = $testRecord->score;
}
}
}
return [$data, Auth::user()->tests()->findOrFail($id)];
}
Try this before excuting return sentence or in it:
array_values($data);
I have inputs array and i need to make a foreach but laravel $request->all() only return last one:
url:
http://localhost:8000/api/ofertas?filter_pais=1&filter_pais=2&filter_pais=3
controller:
public function filtroOfertas(Request $request){
return $request->all();
}
result:
{"filter_pais":"3"}
result should return 1, 2 and 3 and i need to make a foreach in filter_pais.
Any solution? Thanks
Use [] at the key of query string.
http://localhost:8000/api/ofertas?filter_pais[]=1&filter_pais[]=2&filter_pais[]=3
It will be parsed as array.
Repeated parameters make no sense and should be avoided without exception.
But looking at other solutions, there are several:
routes.php
Route::get('/api/ofertas/{r}', 'Controller#index');
Controller:
public function index($r)
{
$query = explode('&', $r);
$params = array();
foreach($query as $param)
{
list($name, $value) = explode('=', $param);
$params[urldecode($name)][] = urldecode($value);
}
// $params contains all parameters
}
Given that the URL has no question marks:
http://localhost:8000/api/ofertas/filter_pais=1&filter_pais=2&filter_pais=3
I have the next code:
$fixed_events = EventMain::find()
->select(["id", "title", "files"])
//->joinWith(['files'])
//->with(['files'])
->asArray()
->all();
How can i get array with "files" value, taking into account, that the "files" is modle's getter like
public function getFiles()
{
return (json_decode($this->all_files, true)) ?: [];
}
Since files is not a relation with EventMain table, I guess the easiest approach would be handle the data and convert with ArrayHelper after coming from db:
<?php
use yii\helpers\ArrayHelper;
$models = EventMain::find()->select(['id', 'title'])->all();
$array = ArrayHelper::toArray($models, [
'app\models\EventMain' => ['id', 'title','files']
]);
var_dump($array);
?>