Eloquent $fillable with nested json keys - php

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.

Related

Laravel 8 – Model instance error - too few arguments to function __construct()

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',
];

show(Model $model) is not working in Laravel 7

I have created a ModelController. In the show(ModelName $model), I have defined the method:
`
show(ModelName $model){
return response()->json(['data'=>$model]);
}
`, but it is not working as expected. It should return the model with its attributes, but it is returning an empty array.
My route is:
Route::resource('model','ModelController');
Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
class ModelName extends Model
{
use Notifiable,SoftDeletes;
protected $fillable = [
'name',
];
}
All the other methods are returning expected values. Just the show method is not working properly. I tried using
show($id){
$model = ModelName::findOrFail($id)
return response()->json(['data'=>$model]);
}
This works perfectly, but I cannot use show(Model $model) this type of function call. I can retrieve user data by the same kind of method.
I can not figure out what the problem is. Does anyone have a solution?
check your route list by cmd php artisan route:list --name=Model
match case in uri, is that same as your (Model $model),
$model should be same as {model} in uri (casesenstive)
Try specifying your model in ModelController like so:
class ModelController extends Controller
{
protect $model = ModelName::class;
}

How to attach a relationship directly on an object?

I don't know if I formulated the question correctly, but whatever.
So when I use the "store" method on my controller, I send two fields, "name" and "fr", both in the same request.
In my controller, I want to be able to create my Model (Room) and attach its relationship to it (RoomTranslation). When I try the following code, it tells me I didn't provide the room_id. Is there an automatic way to achieve this ?
public function store(RoomRequest $request)
{
$request = $request->validated();
$room = new Room;
$room->create($request);
$room->translations()->create($request);
return success('');
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class RoomTranslation extends Model
{
protected $fillable = ['fr', 'room_id'];
public function room() {
return $this->belongsTo('App\Room');
}
}
<?php
namespace App;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use App\RoomTranslation;
class Room extends Model
{
protected $fillable = ['name'];
public function categories() {
return $this->hasMany('App\Category');
}
public function translations() {
return $this->hasOne('App\RoomTranslation');
}
}
Thank you for your help !
P.S. : If there is a cleaner way to write this part of my code, I will be happy to hear how I can improve it.
Thank you !
You can do this:
Room::create($request->only(['name']))->translations()->create($request->only(['fr']));
just look for typo or input names to be correct.
Also in Room model class translations relation if you have multiple languages for every Room should be hasMany, And if you don't have many translations per Room you could just add a column for translation language.

Json Laravel Model

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();

Posting data return blank with a Laravel controller

I have a problem posting data in Laravel 5. I've done a page that post stuff on a controller that would create a new row on a database, according to Eloquent class. But when I post that, I receive a blank page and nothing works.
This is my controller, focused on the affected class:
<?php namespace App\Http\Controllers;
use App\T_subject;
use App\T_reservation;
use Date;
use Request;
use Config;
use Validator;
use Auth;
class TutoringController extends Controller {
public function reserve(Request $request)
{
$reservation = new T_reservation;
$reservation->user_id = Auth::user()->id;
$reservation->subject_code = $request->input('subject');
$reservation->date = $request->input('date');
$reservation->topic = $request->input('topic');
$reservation->save();
return redirect('/tutoring/view/'.$request->input('subject'));
}
}
This is my Eloquent model:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class T_reservation extends Model {
protected $table = 't_reservations';
public function user()
{
return $this->belongsTo('App\User');
}
}
And my routes file:
<?php
Route::post('tutoring/reserve', ['middleware' => 'auth', 'uses' => 'TutoringController#reserve']);
Where's the problem?
In your routes file there is no definied route for your final redirection: '/tutoring/view/'.$request->input('subject').
Also, your model have no fillable property, which should list properties for which you can make a mass assignment. For instance something like this:
protected $fillable = ['user_id', 'subject_code', 'date', 'topic'];

Categories