Laravel Eloquent get only one specific field with relationship and paginate - php

Here my code :
$prestations = Prestation::with('service:name','conciergeries.network:name')->orderBy($orderBy, $orderDirection)->simplePaginate(100);
$res = [
'results' => $prestations,
'total' => Prestation::all()->count(),
];
return $res;
I need to get only the network name and not all datas of "conciergeries" and "network" because actually is too heavy.
I have tried some things like
$prestations = Prestation::with('service:name','conciergeries.network:name')->orderBy($orderBy, $orderDirection)->pluck('network.name')->simplePaginate(100);
Thank you !

When using eager loading with specific columns, you should always include the id column and any relevant foreign key columns in the list of columns you wish to retrieve.
So try this instead:
$prestations = Prestation::with(
'service:id,name',
'conciergeries:id,network_id',
'conciergeries.network:id,name'
)
//->orderBy(...
Don't forget to add/modify any other relevant foreign keys you use, I just guessed these keys.

Related

Get maximum values in column with diferents foreign ids in Laravel

I want to get the largest value from a column, but those values ​​correspond to two different foreign ids, so I want it to return the maximum number for each foreign id. I don't know If I have to use max()... At the moment I am just using groupBy with the two foreign ids.
Here the table in MySqlAdmin. I want to get the maximum bid for each id_group and id_karatekas:
And here is my code:
public function soldKarateka()
{
$response = array('code' => 400, 'error_msg' => []);
self::getBidByKaratekaGroup($response);
return response($response, $response['code']);
}
private function getBidByKaratekaGroup( & $response){
$bidsPerKarateka = DB::table('bids')
->groupBy('id_group','id_karatekas')
->get();
$response = array('code' => 200, 'Karatekas order by group' => $bidsPerKarateka);
}
You should try below code for find max value.
if your table name is bids then it will be ok otherwise change name as per your table name.
DB::table('bids')
->select([DB::raw('MAX(bids.bid) AS maxbid'), 'bids.id_group', 'bids.id_karatekas'])
->groupBy('bids.id_group', 'bids.id_karatekas')
->get()->toArray();
Did you try the max function?
I think the following snippet will work
$data = DB::table('bids')
->select(DB::raw('MAX(bid) as bid'))
->groupBy('id_group', 'id_karatekas')->get();

Laravel Replace existing DB value - Favourites

I am trying to setup a favourites button on an article. The following code works ...
public function favouriteNotfavouriteArticleParent(Request $request){
$data = [];
$data['user_id'] = Auth::id();
$data['person_id'] = GetPersonData()['id'];
$data['article_id'] = $request->get('article_id');
$data['action'] = $request->get('action');
UserFavourites::updateOrCreate($data,$data);
}
However, i want it to firstly check for any existing values set for that article ID. If it has favourite set and notfavourite is clicked, it should remove the favourite table row.
At the minute it just adds a row for favourite and notfavourite. I've attached a screenshot of the current sql behaviour.
Any help is massively appreciated!
UpdateOrCreate takes two arguments. The first argument is an array of attributes to look for and the second argument is an array of attributes to change. If there isn't a row in the database that has attributes from the first array the arrays will essentially be combined to make a new row in the database.
To achieve what you're after you could do the following:
UserFavourites::updateOrCreate([
'article_id' => $request->input('article_id'),
'user_id' => auth()->id(),
], [
'person_id' => GetPersonData()['id'],
'action' => $request->input('action'),
]);
The above will look for a row that matches the article_id and user_id and then either update the person_id and action for that row or (if the row doesn't exist) create a new row with all the attributes.

How to KeyBy where multiple items have the same key

I am using Laravel Collections methods and am trying to key my query results (which are a collection) by the id. The problem is I have multiple entries with the same id, but point to different countries and I want to have all of the values, not just the last one.
Here is my code that i am using so far:
$allCountries = new Collection($allCountries);
$offerCountries = $allCountries->keyBy('id');
dd($offerCountries);
foreach ($offer as $o) {
$o->countries = $allCountries->get($o->id);
}
To explain, my query puts the results in $allCountries which contains ids and countries and those results looks something like this
id=>225, country=>US
id=>225, country=>IT
id=>3304, country=>NZ
Just to give you a quick idea. I want to key this by the id which results in $offerCountries. I then loop thru a previous Collection that contains offers which have a certain ID that relates to the country result by id. So for the offer 225, the countries it contains are US and IT. I loop thru each offer and set the countries object equal to all the $allCountries id that it equals. The problem I have here is keyBy overwrites the value and only takes the last one. I am hoping to get some results like this:
[
225 => countries: {'id' => 225, 'country' => 'US'}, {'id' =>
'225', 'country' => 'IT'}
3304 => ['id' => 3304, 'country' => 'NZ'],
]
Is there a laravel method to do this, or do I need to write my own keyBy so it does not overwrite. If so, how can I get started to write this method?
Thanks
Instead of using keyBy, use groupBy:
$countriesById = collect($allCountries)->groupBy('id');
You could use filter and create a custom filter
$filtered = $allCountries->filter(function ($item) use ($id) {
return $item->id == $id;
});
$filtered->all();

Yii relations using variables of the active model

I have two rows in one of my tables which look like:
id product_id target_product_id description type
1 206587 456 sdfgdfgdfg 0
2 456 206587 fgdgfhghfgfdsgfdghfghfsd 0
When viewing the model for the row with id 1 I wish to get the second row based on where the product_id and the target_product_id are inversed. So I made a relation of:
'linked_product_relation' => array(self::HAS_ONE, 'Accessory', '',
'on'=>'linked_product_relation.target_product_id = product_id
AND link_product_relation.product_id = target_product_id')
However, it seems to only ever return null. I have checked that link_product_relation links to the table, and I get no SQL error, just a null return. If I use the relation with only link_product_relation.product_id = product_id though I do actually get a response, but only the row I am currently looking at. I seem to be missing something.
How can I get my desired output?
Edit
When I add a function to replace the relation:
function getTwinned(){
$a=Accessory::model()->findByAttributes(array('target_product_id'=>$this->product_id, 'product_id'=>$this->target_product_id));
if($a===null)
return null;
else
return $a;
}
It works perfectly.
You did not specify a foreign key ('' in your code). Try something like this:
'linked' => array(self::BELONGS_TO, 'Accessory', array(
'target_product_id'=>'product_id',
'product_id' => 'target_product_id',
)),
For more information also read the manual on this topic here and here.

find by column name cakePHP

Hello I have been trying to understand how to get data from model by the name of field. I am using cakePHP, and I need to retreive a column's data from a table. The syntax is
> "select name from permissions"
So I tried to find out on book.cakephp.org, so I got the field function, but that only gives me the first value, while I have more than one values for this.
I tried do a
$this->Model->find(array('fields'=>'Model.fieldName'));
but I understood that the syntax itself is flawed.
Can somebody let me know what is the method to query based on column name.
$this->Model->find(array('fields'=>'Model.fieldName'))
You forgot the array function. Also:
$this->Model->find(array('fields'=>array('Model.fieldName')))
will work.
findAllBy will find all records based on the field name.
$this->Model->findAllBy<fieldName>(string $value, array $fields, array $order, int $limit, int $page, int $recursive);
For eaxample:
$this->Permission->findAllByName('Some Name');
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#findallby
Found it... hope it will help someone.
$workshop_lists = ClassRegistry::init('Workshop')->find('all',array(
'fields'=>array('user_id', 'title')
),
array(
'conditions' => array('user_id' => $this->Auth->user('id')),
'group' => 'Workshop.user_id',
'order' => 'posted DESC',
));
There is no way you can query out based on column name using one of the cake methods. You have to use the query method.
Syntax: $this->Model->('Select columnname from table');
$this->Model->find('all',array('fields'=>array('Model.fieldName')))
it works for me everytime.
If I understood well and you want not only 1 value but the whole values in the column 'name' from the table 'permissions'. In that case you could use:
$this->Model->find('list',$params);
(see explanation for 'find' here)
for the '$params' part you would use:
$params=array('fields'=>array('name'));
or putting all in a single line:
$arrayOfNames= $this->Model->find('list',array('fields'=>array('name')));
This will give you an array '$arrayOfNames' wich key is the 'id' (primary key) in 'permissions' table and wich value is the corresponding name in the field 'name' from the same table. This is the array would be something like:
'id'=>'name'
[23]=>'name1'
[28]=>'name2'
[29]=>'name3'
............
very much like I think you want. Hope it helps.
$this->Model->find('list', ['valueField' => 'fieldName']);

Categories