laravel 5.5 model relation in json - json

I'm trying to understand, if in laravel 5.5 there is a method that given a model linked to another with an external key, I can obtain the result of the complete join of the attributes of both models. I wanto to avoid to return two models and merge them.
Below the code of my model:
class Event extends Model {
public function location(){
return $this->hasOne('App\Location');
}
}
In the controller I obtain the location information of the respective Event, but in the result I would like to see information of both Event and Location.
In the controller If I call the model with the ORM:
$event = Event::where('name',$name)->first()->location;
$model=$eventLocation->getModel();
return $model;
And obtain this json with
{"id":12,"created_at":null,"updated_at":null,"name":"location_test","event_id":"1"}
That contains only the attributes of the location and not for the Event! How can I show both?
thanks

Try with:
$event = Event::with('location')->where('name', $name)->first();
$location = $event->location;
In this way you will get the event itself and the complete related location as location field.
See the Eager Loading section on the docs.

Try this :
$event = Event::with('location')->where('name', $name)->first();
return $event->toJson();
You will have access to your event with data.location

You can use:
$event = Event::with('location')->where('name',$name)->first();
or:
$event = Event::where('name',$name)->first();
$event->load('location');
Then when you just return model or call $event->toJson() you will have your location relationship loaded.
If you want to get details about loading relationships you can look at laravel eager loading using with() vs load() after creating the parent model

Related

Displaying data based on type of user authentication

So I am have made a laravel authentication application that can log in/register users based on a type and depending on a type they can see different information in this case data tables. I used the laratrust package to do this and works well, but if I want to make this with a vue component that will show the data using some special data grid how would go about doing it as the controller which I am using where the data is collected but is also the place where the view which the user will see depending on the type of user is also checked. So, how will I send the json data to the vue component and what other things do I need to consider.
Here is the controller in laravel:
class DashboardController extends Controller
{
public function index()
{
if(Auth::user()->hasRole('user')){
$posts = DB::select('select * from office');
return view('userdash',['posts'=>$posts]);
}elseif(Auth::user()->hasRole('administrator')){
$posts = Post::all();
return view('administratordash',['posts'=>$posts]);
}elseif(Auth::user()->hasRole('admin')){
$people = DB::select('select * from office');
$posts = Post::all();
return view('dashboard',['posts'=>$posts,'people'=>$people]);
}
}
}
One of the things I tried was
return response(view('userdash',array('posts'=>$posts)),200,['Content-Type' => 'application/json']);
This way I can just send the json data and then render it in the view component. But I am not sure if it is working as I get back a bunch of html and some of the data in the database but not all of it. Also not sure how this can be passed to the view component. Maybe as a prop but not sure.
Any and all help and suggestions are appreciated.
As you are responding from the controller with different views, you can just check for any variables sent with the wiew in your view and once your variables are at your disposal in the view yo can serialize them using $myVar=$myVariable->toJson() if they are laravel collections or json_encode($myVariable) if they are simple arrays.
Then you can
<my-component :data ={{$myVar}}/>

How to create a model object in yii2 by string name?

I need to create a model by string name that it is a variable.
function($modelName){
$modelName= "backend\\models\\".$modelName;
$modelClass = Yii::createObject([
'class' => $modelName,
]);
$model = $modelClass::find();
}
when I pass Book(it is extracted form DB) as modelName to function, it throws an error: Class backend\models\Book does not exist.
but when I write $modelName= "backend\\models\\Book"; it works fine.
I know it is because of run time and compile time. but I don't know how to solve it. because $modelName is Characterized at run time.
You are accessing to a static method using an object. You should access to the static method just using the class name eg:
$modelName = 'backend\models\\' . $modelName;
$model = $modelName::find();
And remember that $modelName::find() don't return a model but just the query object for a model. To obtain a model you should use eg: $modelName::find()->where(['id'=>$your_value])->one();

Laravel - Eloquent: Polymorphic relations with namespace

My situation is: a Calendar belongs to a Customer or Salesman
Because I also have classes like Event and File, I used the namespace App\Models for all my model classes.
so I set up the polymorphic relation:
in Calender.php
public function user() {
return $this->morphTo();
}
in Customer.php and Salesman.php
public function calendars() {
return $this->morphMany('App\Models\Calendar', 'user');
}
Now when i do
$calendar= Calendar::find(1); //calendar from a salesman
$calendar->user; //error here
...
I get this error message:
Symfony \ Component \ Debug \ Exception \ FatalErrorException
Class 'salesman' not found
I noticed that 'salesman' is low cased, maybe this is the problem?
and this is what I get from Laravels stacktrace
open: /var/www/cloudcube/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
// foreign key name by using the name of the relationship function, which
// when combined with an "_id" should conventionally match the columns.
if (is_null($foreignKey))
{
$foreignKey = snake_case($relation).'_id';
}
$instance = new $related; //HIGHLIGHTED
I had a similar error before on this line, when I was messing with the namespaces, so I guess it has something to do with that. Is there any way I can tell the morphTo() method to use the correct namespace?
Or is it something else causing this issue?
Also found this solution, but can't seem to get it working:
Polymorphic Eloquent relationships with namespaces
I found a solution that worked for me.
I always define relationships with the correct namespace, for example in Calendar:
public function events() {
return $this->hasMany('App\Models\Event');
}
My problem consisted out of 2 complications:
$calendar->user() with the morphTo(...) function was not working because my models were in a namespace, and morphTo(...) had no way of giving this namespace.
$salesman->calenders()->get() returned and empty list, although my relations in the database were there. I found out this is because of bindings with the query.
Solution for 1. : Writing a custom morphTo(...) function in Calendar to override the one of Laravel. I used the source of Laravels morphTo(...) as a base. The final statement of this function is return $this->belongsTo($class, $id);
There $class must be the namespaced class name. I used basic string operations to pull that off.
Solution for 2. : Writing a custom morphMany(...) function in Salesman and letting it return a MyMorphMany(...) similar to what Polymorphic Eloquent relationships with namespaces described.
The problem here is that $query that is passed to the MyMorphMany constructor has the wrong (namespaced) binding. It will look for where user_type = "App\\Models\\Salesman".
To fix this I used a custom getResults() function in MyMorphMany which overrides the default Laravels implementation, there I changed the bindings to use the correct, un-namespaced lower cased, class name. Then I called this getResults() function in the get() function of the MyMorphMany class.
I used $query->getBindings() and $query->setBindings() to correct the bindings.
Hope this saves someone else a few days of work, like it would have saved me :)

Doctrine 2 namespace issue

I'm using Zend Framework 1 with the Bisna library to integrate Doctrine 2. I generated my Entities from my database model with the Doctrine 2 CLI. This is all working fine, except for the setter methods for associated records. The argument they accept must be of a specific namespace (\Category here).
class Article
{
public function setCategory(\Category $category = null) {
$this->category = $category;
return $this;
}
}
However, when I do this:
$article = $this->em->getRepository('\Application\Entity\Article')->find(1);
$category = new \Application\Entity\Category();
$category->SetName('New Category');
$article->setCategory($category);
I get the following fatal error: Argument 1 passed to Application\Entity\CategoryField::setCategory() must be an instance of Category, instance of Application\Entity\Category given.
When I change the setter method to accept \Application\Entity\Category objects, it's working of course. Should I do this for every generated method, or are there other options? This is the first time I'm using namespaces, so it might be something simple.
You can always add this to the top of your class file: use \Application\Entity\Category; and then simply reference it later like so: public function setCategory(Category $category = null)
Check out: http://php.net/manual/en/language.namespaces.importing.php for more info about use
Otherwise you would have to reference the full namespace otherwise your application does not know that \Category is a reference to \Application\Entity\Category

prestashop: Display method results in JSON

I'm going to develop a method inside my Prestashop module to fetch list of products and return the result as JSON. I have no problem to get list of products however I don't know to use which hooks and how to return JSON result instead of returning back to a Prestashop page.
The best way is to use a specific controller in your module. the result of the controller is available by an URL.
(Your controller class have to extend the "ModuleFrontController" class)
In your module controller, you should change the default constructor by:
public function __construct($response = array()) {
parent::__construct($response);
$this->display_header = false;
$this->display_header_javascript = false;
$this->display_footer = false;
}
And, in your "postProcess" method, simply echo the string you want, using this for example:
$json = json_encode( (array)$object );
Finally, in a template, you can generate a link to this controller using:
{$link->getModuleLink('mymodule', 'mycontrolleurname', [], true)}