How to write model in Laravel without creating Database and with function getData that returns Json? Something like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Table extends Model
{
protected $table = 'table';
protected $fillable = [
'atribute1',
'atribute2',
'atribute3',
'atribute4'
];
}
But without database.
I would be grateful for help
You need to extend Model only if you're using Eloquent.
If you just need to get json data from somewhere, create usual class which gets data from somewhere and returns JSON:
class MyModel
{
public function getJsonData()
{
$jsonData = // get json data from somewhere
return $jsonData;
}
}
Register this class in composer.json file, run composer dumpauto and use your class:
$model = new MyModel();
$data = $model->getJsonData();
Related
I am trying to predefine a structure for internal POST Requests and the json structure will look similar to this:
{
"name":"max",
"prename":"maxmax",
"friends": {
"quantity":3
"online":1
}
}
My Model looks like this:
<?php
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model;
class User extends Model
{
protected $connection = "mongodb";
protected $fillable = ["name", "prename", "friends"];
}
Based on that my Controller looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use GuzzleHttp\Psr7\Response;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
class UserController extends Controller
{
public function createUser(Request $request) {
$user = User::create($request->all());
return response()->json(["message"=>"created"], 201);
}
}
Now it is possible to pass everything to the friends key and it will be stored in the database. Is it possible to define a nested json in the $fillable attribute of the Model or is there another effective way to make sure that only "quantity" and "online" can be stored in the database, while using:
$user = User::create($request->all());
In reality my POST-Body is much bigger and has more nested keys, so i guess it wouldn't be effective to proof each key individually.
I’m kind of new to Laravel and the whole API architecture, so my question may seem dumb at first.
My basic setup:
Laravel 8;
PHP 8;
routes\api.php
Route::post('/categories/',[ApiCategoriesInsertController::class, 'insertCategories'], function($insertCategoriesResults) {
return response()->json($insertCategoriesResults);
})->name('api.categories.insert');
\app\Http\Controllers\ApiCategoriesInsertController.php (created with php artisan make:controller)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
// Custom models.
use App\Models\CategoriesInsert;
class ApiCategoriesInsertController extends Controller
{
private mixed $ciAPI;
public function __construct(Request $req)
{
}
public function insertCategories(Request $req): array
{
$this->ciAPI = new CategoriesInsert(['testing'=>'debug']);
return [‘status’ => ‘OK’];
}
}
\app\Models\CategoriesInsert.php (created with php artisan make:model)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CategoriesInsert extends Model
{
use HasFactory;
public function __construct(array $objParameters)
{
}
}
When I make a post to http://localhost:8000/api/categories, Laravel logs the following error:
local.ERROR: Too few arguments to function App\Models\CategoriesInsert::__construct(), 0 passed in … Too few arguments to function App\\Models\\CategoriesInsert::__construct(), 0 passed in …
Anyone knows what’s wrong or missing in my architecture?
Thanks!
Make your model's constructor compatible with parent.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CategoriesInsert extends Model
{
use HasFactory;
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
}
}
Also, notice, that when you call new CategoriesInsert(['testing'=>'debug']), you do not save the data in your database. Use:
$insert = new CategoriesInsert(['testing'=>'debug']);
$insert->save();
Or:
CategoriesInsert::create(['testing'=>'debug']);
you don't need to pass data to model
change your code to bellow code:
public function insertCategories(Request $req): array
{
CategoriesInsert::create(['testing' => 'debug']);
return [‘status’ => ‘OK’];
}
key of passed array is your filed name in database, and value stored data
also you should define fillable parameter in model
protected $fillable = [
'title',
'slug',
'priority',
];
Laravel version is 7.0:
I have setup model relationships like this.
<?php
namespace App;
class Template extends Model
{
protected $fillable = ['header_id', 'content', 'name'];
public function header()
{
return $this->belongsTo('App\Header', 'header_id');
}
}
In controller I can get template object with header.
<?php
namespace App\Http\Controllers;
use App\Template;
class TemplateController extends Controller
{
public function show($id)
{
$template = Template::find($id);
}
}
Now I can use $template->header in view.
How can I pass different header_id and get header relationship object?
I would like to do as following:
<?php
namespace App\Http\Controllers;
use App\Template;
class TemplateController extends Controller
{
public function show($id, $temp_header_id)
{
$template = Template::find($id);
$template->header_id = $temp_header_id;
}
}
I want to get new header relationship in view:
Is there any way to return new header relationship when I do $template->header in view.
Thank you
Yes you can do what you are looking to do, but kinda defeats the relationship in the database. You can assign any id to $template->header_id and then load the relationship using that new value:
$template->header_id = 897;
// load the relationship, will use the new value
// just in case the relationship was already loaded we make sure
// to load it again, since we have a different value for the key
$template->load('header');
$template->header; // should be header with id = 897
I am trying to simply save a model to the database via a controller without setting the fields directly but instead having them set in the constructor of said object.
Here is the class handling the logic. If the commented out line
//$todoItem->item = $todo; is uncommented, it works fine and saves whatever is entered in $todo in the database. However, I would like to set that value in the constructor of the task object and not need to manually specify it. I found this question: Laravel with Eloquent doesn't save model properties on database suggesting I could set the property as protected and have it work, but that still does not.
NewTodo.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class NewTodo extends Controller
{
public function saveTodoItem(Request $request)
{
$todo = $request->input('content');
$todoItem = new \App\Task($todo);
//$todoItem->item = $todo;
$todoItem->save();
return view('testview', ['name' => $todoItem->getItem()]);
}
}
Task.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
protected $item = null;
function __construct($newItem)
{
$this->item = $newItem;
}
function getItem()
{
return $this->item;
}
}
Summary, database entry being stored as blank unless $todo->item is manually set when from what I can $todo->item is being set in the constructor.
You don't need to specify these in the constructor. You can use Mass Assignment
Model:
class Task extends Model
{
protected $fillable = ['item'];
}
Controller:
class NewTodo extends Controller
{
public function saveTodoItem(Request $request)
{
$todo = $request->input('content');
$todoItem = new \App\Task::create(['item' => $todo]);
return view('testview', ['name' => $todoItem->getItem()]);
}
}
I would like to load my Model in my Controller. The model is not associcated with a table in the database, thus it is probably not able to follow CakePHP's ORM.
I have the following code currently (this is my Model):
<?php
namespace App\Model\Json;
use Cake\Filesystem\File;
class Processes
{
public static function getData()
{
$file = new File('process_data.json');
$json = $file->read(true, 'r');
$jsonstd = json_decode($json);
// remove STD classes
$json2array = json_decode(json_encode($jsonstd), true);
$cpu = array();
foreach ($json2array as $key => $row)
{
$cpu[$key] = $row['cpu_usage_precent'];
}
array_multisort($cpu, SORT_DESC, $json2array);
// return data
return $json2array;
}
}
I call the Model through the following code (in the controller):
$json2array = $this->Processes->getJson();
$this->set('data', $json2array);
I am not able to call it in my Controller somehow. I keep getting the following error:
Some of the Table objects in your application were created by
instantiating "Cake\ORM\Table" instead of any other specific subclass.
Please try correcting the issue for the following table aliases:
Processes
Here is an example, How to access Model without CakePHP ORM in CakePHP 3.x
In Model : Processes
In the file /path_to/src/Model/Table/Processes.php
namespace App\Model\Table; #Define the namespace
use Cake\Filesystem\File;
class Processes{
public static function getData(){
/*Your codes here*/
}
}
In Controller : Bookmarks
In the file /path_to/src/Controller/BookmarksController.php
namespace App\Controller;
use App\Model\Table\Processes; #Using PSR-4 Auto loading
use App\Controller\AppController;
class BookmarksController extends AppController{
public function tags(){
$data = Processes::getData(); #Now you can assess Data
}
}
Here is the details about Auto loading with PSR-4