Why do I have different dump in PHP and JSON? - php

I use Laravel Eloquent for my project. I get different object results with futher coding.
Php dump (var_dump(), dd(), dump()) object without unnecessary data, file json_encode spawns calculated data including loading something what was not required.
I have two model classes:
class Product extends Model
{
public function reviews()
{
return $this->hasMany(Review::class);
}
}
class Review extends Model
{
public function product()
{
return $this->belongsTo(Product::class);
}
}
To get a product I use
$product = App\Product::find(1)
But since I want to send data to JSON, I need to just load it by typing:
$product->reviews
But I don't want to load it, I just want to get additional calculated data without loading all reviews inside my json
$product['reviews_statistics'] = count($product->reviews);
I expect to find out how to set data for JSON without loading all $product->reviews

I would recomend You to try eagerloading the count:
$product = App\Product::withCount('reviews')->find(1)

Related

Laravel Excel 3.1 styling without model

I am using laravel-excel.com in my Laravel project.
Since data is not coming from a specific model, I didn't want to create a dummy model class and I generate the excel file directly:
return (new \Illuminate\Support\Collection($data))->downloadExcel(
'informe.xlsx',
null,
false
);
($data is a two-dimensional array with data of the unique data-sheet)
I wonder if there is any way to apply some style on columns (width, font-weight, etc.).
As far as I see it is possible ( like explained here) if I create a model for this excel.
Is it possible without?
It looks like it is impossible to apply styles on excel sheet without having a model.
However, I found a trick that makes it very easy to move my code to a model, I leave it here in case it might help somebody.
The idea is to pass $data array (which I retrieve using a service) as a parameter to the constructor:
Controller:
return Excel::download(new MyExport($data), "$fileName.xlsx");
app/Exports/MyExport.php:
<?php
namespace App\Exports;
use \Illuminate\Support\Collection;
class ActuacionesExport implements FromCollection
{
private $data;
function __construct($data) {
$this->data = $data;
}
public function collection()
{
return new Collection($this->data);
}
}
As you can see, the model does not do anything except of returning a Collection instance, but it permits adding styling, column width, drawings - whatever you need in your excel!

Call a Model method using Laravel Relationship

I'm currently trying to use Laravel Relationships to access my achievements Model using User model, I use this relationship code:
public function achievements()
{
return $this->hasMany('App\Models\User\Achievement');
}
I can easily make some eloquent queries, however I can't access any method that I created there, I can't access this method:
class Achievement extends Model
{
public function achievementsAvailableToClaim(): int
{
// Not an eloquent query
}
}
Using the following code:
Auth::user()->achievements()->achievementsAvailableToClaim();
I believe that I am using this Laravel function in the wrong way, because of that I tried something else without using relationship:
public function achievements()
{
return new \App\Models\User\Achievement;
}
But that would have a performance problem, because would I be creating a new class instance every time I use the achievements function inside user model?
What would be the right way of what I'm trying to do?
it's not working because your eloquent relationship is a hasMany so it return a collection. you can not call the related model function from a collection.
you can var dump it on tinker to understand more what i mean.
You can use laravel scopes.Like local scopes allow you to define common sets of constraints that you may easily re-use throughout your application.
In your case you use this like, Define scope in model:
public function scopeAchievementsAvailableToClaim()
{
return $query->where('achivement_avilable', true);
}
And you can use this like :
Auth::user()->achievements()->achievementsAvailableToClaim();

How do i delete one row in my SQLite table?

I'm trying to delete one row of data from my sql table called "cart".
It seems to me that it can not find the id called "cartid". im using a program called insomnia and it wont take my input it feels like.
it is gettting a error that is called :"MethodNotAllowedHttpException"
im using laravel 5.4, it is a requirement for me.
i have other functions that work and i do not understand why this one does not.
https://imgur.com/a/T0aOwJF
some snapshots from my code
i have tried to use
Route::delete('cart-remove/{id}', 'CartController#delete');
and alot more
this is in my 'api.php' file:
Route::delete('cart-remove', 'CartController#delete');
this is in my file called 'CartController':
class CartController extends Controller {
public function delete($id) {
DB::table('cart')->where('cartid', '=', $id)->delete();
return response($id, 200);
}
}
i want to get the id from my program called 'insomnia' to remove that id in my sqlite database.
Use the model's destroy method when deleting entries from the database:
use App\SomeModel;
class SomeController extends Controller {
public function destroy($id) //or delete($id)
{
SomeModel::destroy($id);
return response($id, 200);
}
}

Laravel 5: Access database data from within model

I'm trying to use Laravel to access some data from the database. I have setup my model, which works fine, however I'm trying to fetch some data from another table by creating a method within the model which fetches the data and sets a property of the model equal to the fetched data.
To fetch the data, I'm trying to use the $this->id property to fetch this row's ID and use it to fetch data from another table (eg: SomeOtherModel::where('other_id', '=', $this->id)->get();)
However, none of the data from the database seems to have been fetched by the model at this point (eg: $this->id is null). My constructor looks like so:
public function __construct() {
parent::__construct();
$this->other_data = $this->getOtherData();
}
Is there any way to call the $this->id property from the database so I can use it within the model itself?
Your syntax seemed to me wrong:
SomeOtherModel::where('other_id', '=', $this->id)->get();
Can you try this:
SomeOtherModel::where('other_id', $this->id)->get();
Reference: https://laravel.com/docs/5.1/eloquent#retrieving-single-models
I hope this helps .
The solution is explained here:
class ExampleModel extends Model {
protected $appends = ['otherdata'];
public function getOtherdataAttribute() {
return $this->getOtherData();
}
}

PHP: Should a Model in MVC be implemented as singleton? [duplicate]

This question already has answers here:
How should a model be structured in MVC? [closed]
(5 answers)
Closed 9 years ago.
In the ideal world one should not rely on singletons, the model in the controller and model inside the view would be 2 different instances. The problem arises when the controller sets a state and the view presentation depends on that state. For example:
class MyController extends Controller {
public function __construct(ModelUsers $cModel)
{
$this->model = $cModel;
}
public function action_Search($username) {
$this->model->filterByUsername($username);
}
}
class MyView extends View {
public function __construct(ModelUsers $vModel)
{
$this->model = $vModel;
}
public function users() {
return $this->model->getUsers();
}
}
How to share data between the controller model and the view model?
Starting from basics
A view requests from the model the information that it needs to generate an output representation to the user.
It means the view should be only responsible for showing the information. Just for that. You can also do some things like triming, chaning text size etc. but you shouldn't do some countings there or more complicated operations.
A model notifies its associated views and controllers when there has been a change in its state. This notification allows the views to produce updated output, and the controllers to change the available set of commands.
Model should be responsible for doing data operations. You can use it for example to get the records from database. It just be responsible for data handling.
A controller can send commands to its associated view to change the view's presentation of the model (e.g., by scrolling through a document). It can also send commands to the model to update the model's state (e.g., editing a document).
Controler is kind a proxy between model and view. You get there params and according to this params you set proper action of your controller. This action should create correct model object and use it to get data then assign to the view.
I've never used singleton in models. If you need some classes that would help MVC structure you can use helpers and as Hast suggested Registry pattern. I'm not a fan of using singleton.
You may also want to look at When to use singleton
So your question.
Controler -> model = Passing data via arguments of model's methods
Model -> controler = If reference then just work on it, if argument then do something and return result
Controler -> view = assign proper data to be viewed.
View->controller = go to special url to make data or use ajax request to retrieve it.
You can use Registry or Dependency injection instead.
Also in some cases you may pass some data to your view class as array. Like this:
class MyView extends View {
private $data = array();
public function __construct($data)
{
$this->data = $data;
}
public function users() {
return $this->data['model']->getUsers();
}
}
Of course you have to pass model when you caling the View class from your controller (or wherever you make call).

Categories