Laravel Eloquent : How to generate a fake column in a Json response? - php

I have two models: Uai and Information with an hasOne relationship.
Uai (uai_id, a)
Information (uai_id, b)
I want to generate a Json response witch contains :
all the Uai records
a "fake" column whitch says true if the hasOne Relationship exists between Uai and Information and false if there is no relationship
Any idea ?
Thanks in advance
Paguemaou
Edit One
Thanks jedrzej.kurylo for your answer.
How can I use the uai_id of the current row in the fake column getter ? I othen use getters and seeters but I never try to use the content of another column. Can you give me an example ?
If I understand, I can use the fake column name in a select like others columns name. I am true ?

Eloquent allows you to easily add custom field to a model's JSON representation.
Firstly, you need to define a list of additional fields by defining $appends property in your model class:
protected $appends = ['fakeColumnName'];
Secondly, add a getter for the fake column that will provide the value for custom column:
public function getFakeColumnNameAttribute() {
//here add the code that will return custom column's value
}

Related

save a belongsTo relationship

I have a classic one-to-many relationships, and I am trying to save the model of the belongsTo side.
The 2 models have these relationships:
// Model myModel
function domicile()
{
return $this->belongsTo('App\Address', 'domicile_id');
}
// Model Address
function myModels()
{
return $this->hasMany('App\MyModel', 'domicile_id');
}
This is what I am tryng to do to save it:
$myModel->domicile()->save($my_array);
With this code I get the error:
Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::save()
if I use this code (without the brackets):
$myModel->domicile->save($my_array);
I do not get any error but the model is not saved.
I know there is the method associate, but I need to update an existent record, not to save a new one.
Because $myModel->domicile()->save($my_array); is totally different to $myModel->domicile->save($my_array); :
$myModel->domicile() will produce a BelongsTo object, doesn't support the save because save is a method of HasMany instances, instead for BelongsTo instances you should use associate(YourModel)
$myModel->domicile will produce a Model object of the associated element, which support the save(array) method, but that array is a options array, as api says https://laravel.com/api/5.7/Illuminate/Database/Eloquent/Model.html#method_save
So in other words, if you have a one (address) to many (domicile) relation, if you want to associate to the address one or many domiciles, you have to use save or saveMany (https://laravel.com/api/5.7/Illuminate/Database/Eloquent/Relations/HasMany.html#method_save), instead if you want to associate to a domicile a address, you should use associate (https://laravel.com/api/5.7/Illuminate/Database/Eloquent/Relations/BelongsTo.html#method_associate)... keep in mind that if you want to do this, you should call the properties with the brackets, in order to have back a HasMany object or a BelongsTo object, and not a Model or a Collection (which you will get if you call the properties without the brackets)
Instead of using the save function, in order to save a belongsTo relationships you have to use the fill function.
In this way:
$myModel->domicile->fill($my_array);
$myModel->domicile->save();
You must use associate() + save() in order to store a BelongsTo relationship:
$myModel->domicile()->associate($domicile);
$myModel->save();
See Laravel Docs

Is possible get olny form fields have Similar Name of model properties in update method of resource controller

I have a Course Model that have many fields like this :
course_id
title
description
creator
start_date
end_date
reg_start_date
reg_end_date
picture
lesson_count
cost
status
active
teacher
created_at
updated_at
deleted_at
And I have a Form to edit a specified Model. action attribute of the edit form tag is referenced to course.update route.
In the edit Form,in addition to fields with same names of above Model properties, there are many other form fields that not related to Course Model (and used for manyTomany relations or other operations)
Now in public update method , when I want to use Eloquent update() method , Since the number of irrelevant field names are many, I must to use except() method for incoming request. like this :
public
function update (StoreCourseRequest $request, $id)
{
$data = $request->except(['search_node', '_token', 'start_date_picker', 'end_date_picker', 'reg_start_date_picker', 'reg_end_date_picker', 'orgLevels', 'courseCats','allLessonsTable_length']);
$course = Course::findOrFail($id);
$course->update($data);
$course->org_levels()->sync($request->get('orgLevels'));
$course->course_categories()->sync($request->get('courseCats'));
$result = ['success' => true];
return $result;
}
As you see on usage of $request->except() method, I passed many field names to it to filter only proper attributes for use in $course->update($data);.
Now my Question is that Are there any way that we can get only same name model attributes from a field name?
If I understand your question correctly you are trying to avoid having to use the except() method for incoming requests, correct?
If that is the case, you can just skip it altogether and pass the entire request to the update() method as it will only update matching fields (provided they are listed as "fillable" in the method class). This process is called "mass-assignment".

laravel Eloquent one to many two relationship. OpenCart table style

How to implement information and information_description tables in laravel Eloquent Model ? Some how it need to set language, because a title should be a one record.
$information = App\Information::find(1);
$information->title
tables structure
You can review how to do this, and plenty more, by reading the documents by Laravel. They are a great help and this particular question has an example and everything. Having said that, I'll help with getting you started.
Define a relationship in either model, information or information_description, or both. For brevity, I'll use information only.
Pass the foreign_key and local_key in the hasMany() relationship since it differs from Laravel's default behavior.
So we have a model that now looks like:
class Information extends Model
{
/**
* Get the descriptions for the Information model.
* Note the 2nd and 3rd arguments in the method
* which define foreign_key and local_key.
*/
public function description()
{
return $this->hasMany('App\InformationDescription', 'information_id', 'information_id');
}
}
Now that you have the relationship defined, you can perform your query.
// Get the description for the information
$information = App\Information::find(1)->description;
// Iterate over the results
foreach ($information as $description) {
$description->title;
}
The table naming convention used is a little odd, but if I understand it correctly, this will work. Hope it helps.

How to assign relation when working with pivot table in Laravel 4?

Details
I have 3 tables :
catalog_downloads
export_frequencies
export_frequencies_catalog_downloads (Pivot Table)
Diagram
I am not sure if I set the relation between them correctly.
Please correct me if I am wrong.
Here is what I did
In CatalogDownload.php
public function export_frequencies(){
return $this->belongsToMany('ExportFrequency','export_frequencies_catalog_downloads','export_frequency_id','catalog_download_id');
}
In ExportFrequency.php
public function catalog_downloads(){
return $this->belongsToMany('CatalogDownload','export_frequencies_catalog_downloads','export_frequency_id','catalog_download_id');
}
Questions
According to my diagram - Did I assign the relationship correctly ?
I hope I didn't mix up between hasMany and belongsTo
Will I need a class or a model for a Pivot Table ?
Thanks
Since export_frequencies is in the CatalogDownload model you have to invert the ID's because the parameters of belongsToMany are as follows:
1. Name of the referenced (target) Model (ExportFrequency)
2. Name of the Pivot table
3. Name of the id colum of the referencing (local) Model (CatalogDownload in this case)
4. Name of the id colum of the referenced (target) Model (ExportFrequency in this case)
what leads to this function:
public function export_frequencies(){
return $this->belongsToMany('ExportFrequency','export_frequencies_catalog_downloads','export_frequency_id','catalog_download_id');
}
The other function was correct.
If you had some data in your pivot table, for instance a colum with the name someCounter then you will have to tell the relation to load that column when creating the pivot object like this:
public function export_frequencies(){
return $this->belongsToMany('ExportFrequency','export_frequencies_catalog_downloads','export_frequency_id','catalog_download_id')->withPivot('someCounter');
}
That will load the column and make it avalible like this:
$catalogDownload->export_frequencies()->first()->pivot->someCounter;
You will need a separate Pivot Model if you need to do some special handling for the fields or if that pivot itself has a relation of its own but then you might consider using a full blown model instead of a pure Pivot Model.
As an added note to the accepted answer, you are able to set up your many to many relationships without referencing the pivot table and the relevant id's as long as you follow a specific convention.
You can name your pivot table using singular references to the related tables, like 'catalog_download_export_frequency'. Notice the alphabetic order of the singular references.
Then you can simply do:
// CatalogDownload Model
public function exportFrequencies()
{
return $this->belongsToMany('ExportFrequency');
}
// ExportFrequency Model
public function catalogDownloads()
{
return $this->belongsToMany('CatalogDownload');
}
This will then allow you to run queries using the query builder or Eloquent like:
$catalogDownload->exportFrequencies()->get(); // Get all export frequencies for a specific CatalogDownload.
Or
$this->catalogDownload->with('exportFrequencies')->find($id); // Using eager loading and dependency injection, when CatalogDownload is assigned to $this->catalogDownload
Hope this helps!

Laravel belongsToMany to return specific columns only

So I have a many to many relationship between Users and Photos via the pivot table user_photo. I use belongsToMany('Photo') in my User model. However the trouble here is that I have a dozen columns in my Photo table most I don't need (especially during a json response). So an example would be:
//Grab user #987's photos:
User::with('photos')->find(987);
//json output:
{
id: 987,
name: "John Appleseed",
photos: {
id: 5435433,
date: ...,
name: 'feelsgoodman.jpg',
....// other columns that I don't need
}
}
Is it possible to modify this method such that Photos model will only return the accepted columns (say specified by an array ['name', 'date'])?
User.php
public function photos()
{
return $this->belongsToMany('Photo');
}
Note: I only want to select specific columns when doing a User->belongsToMany->Photo only. When doing something like Photo::all(), yes I would want all the columns as normal.
EDIT: I've tried Get specific columns using "with()" function in Laravel Eloquent but the columns are still being selected. Also https://github.com/laravel/laravel/issues/2306
You can use belongsToMany with select operation using laravel relationship.
public function photos()
{
return $this->belongsToMany('Photo')->select(array('name', 'date'));
}
Im assuming you have a column named user_id. Then you should be able to do the following:
public function photos()
{
return $this->belongsToMany('Photo')->select(['id', 'user_id', 'date', 'name']);
}
You have to select, the foreign key, else it will have no way of joining it.
Specifying the exact columns you want for the Photos relationship will likely end up biting you in the butt in the future, should your application's needs ever change. A better solution would be to only specify the data you want to return in that particular instance, i.e. the specific JSON response you're delivering.
Option 1: extend/overwrite the toArray() Eloquent function (which is called by toJson()) and change the information returned by it. This will affect every call to these methods, though, so it may end up giving you the same problems as doing select() in the original query.
Option 2: Create a specific method for your JSON response and call it instead of the general toJson(). That method could then do any data building / array modifications necessary to achieve the specific output you need.
Option 3: If you're working with an API or ajax calls in general that need a specific format, consider using a library such as League/Fractal, which is built for just such an occasion. (Phil is also working on a book on building APIs, and it doesn't suck.)

Categories