Laravel, display data where all Ids are matched - php

In controller index function
I'm picking up which news ids are matching with a pack id:
$content_pack_news_array = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->get();
Using dd I get this result which I need to access news_id of all elements in it
Illuminate\Support\Collection {#3017 ▼
#items: array:2 [▼
0 => {#2376 ▼
+"news_id": 2
+"content_pack_id": 2
}
1 => {#3010 ▼
+"news_id": 4
+"content_pack_id": 2
}
]
}
How to return data that matched with ids:
"news_id": 2
"news_id": 4
Inside:
$news = News::with(['media', 'assigned_content_packs'])->where('id' , $news_id)->get();
If I use
$content_pack_news = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->first();
It works but it gets only first matching item to display.
Any help appreciated.

You can use pluck, to get the ids out.
$newsIds = DB::table('content_pack_news')
->where('content_pack_id' , $content_pack_id)
->pluck('news_id');
Pluck works great in combination with whereIn(), that checks a column against an array.
$news = News::with(['media', 'assigned_content_packs'])
->whereIn('id' , $newsIds)
->get();

You can do it in single query using sub query as:
$news = News::with(['media', 'assigned_content_packs'])
->whereIn('id', function($query) use($content_pack_id){
$query->select('news_id')
->from('content_pack_news')
->where('content_pack_id', $content_pack_id);
})
->get();

if i correct you only asking the first.
$content_pack_news = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->first();
change it to get(); then you get all records.
$content_pack_news = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->get();

Related

Laravel Getting id's from a table and inserting them into another table

Trying to get matching id's from a table and inserting them again in the same table under differnet relationship.
$contentPack = ContentPack::find($id);
$cloned_pack_goals = DB::table('content_pack_goal')->where('content_pack_id' , $contentPack->id)->get();
$cloned_pack_goal_ids = $cloned_pack_goals->goal_id;
Produces Exception
Exception
Property [goal_id] does not exist on this collection instance.
dd($cloned_pack_goals); outputs:
Illuminate\Support\Collection {#2466 ▼
#items: array:2 [▼
0 => {#3129 ▼
+"goal_id": 4
+"content_pack_id": 2
}
1 => {#2467 ▼
+"goal_id": 9
+"content_pack_id": 2
}
]
}
How to get goal_ids from the output to insert them into the same table again but with a different relation?
$newPack = $contentPack->replicate();
DB::table('content_pack_goal')->insert(['content_pack_id' => $newPack->id,'goal_id' => $cloned_pack_goal_ids]);
Am doing something wrong when getting the ID's and when inserting them. tried using ->first(); it works but only one id gets inserted
$cloned_pack_goals is a collection, so you need to exclude goal_ids from all collection records separately.
This snippet may help you:
$cloned_pack_goal_ids = DB::table('content_pack_goal')->where('content_pack_id' , $contentPack->id)->pluck('goal_id')->toArray();
foreach($cloned_pack_goal_ids as $key => $goal_id) {
DB::table('content_pack_goal')->insert(['content_pack_id' => $newPack->id,'goal_id' => $goal_id]);
}
To get an array of only the Ids, use pluck() and toArray()
$cloned_pack_goal_ids = DB::table('content_pack_goal')
->where('content_pack_id' , $contentPack->id)
->pluck('goal_id') // returns a collection of only Ids.
->toArray(); // returns an array from the collection.
Write your query in this format this will give you the require output:
$cloned_pack_goals = DB::table('content_pack_goal')->where('content_pack_id' , $contentPack->id)->get()->toArray();
$cloned_pack_goal_ids = $cloned_pack_goals[0]->goal_id;

How to get a result without using [0]

I'm running this query
$results = DB::connection('selection')
->select("
SELECT id, name, email
FROM users
WHERE email = $this->email
");
I expect to only get on result from this, which I do get, this is my output
array:1 [
0 => {
+"id": 1
+"name": "Ted Wood"
+"email": "tedwood#email.com"
}
]
What I would like to know is how can I access name without having to do $results[0]->name I would like to do $results->name.
Since it's only 1 item I'm getting I don't see a need for a foreach loop
Use reset pointer like this
reset($results)->name
using first
$results =collect(DB::connection('selection')
->select("
SELECT id, name, email
FROM users
WHERE email = $this->email
"))->first();
but i think the best way to do it would be like:
$results = DB::connection('selection')->table('users')->select('id', 'name', 'email')
->where('email',$this->email)->limit(1)->first();
DB::select() returns an array. The first() method works with collections, so you need to wrap the array in the collection to use the first() method.
$results = collect($results)->first()

Execute SQL functions with Laravel 5

I have SQL functions stored on my database.
However, I can not call them.
$nb = DB::select('SELECT nb_seances_archivees()');
The result is :
array:1 [▼
0 => {#186 ▼
+"nb_seances_archivees": 0
}
]
But the desired result is just 0.
Thank's for help !
By default DB::select return an array of objects, you can use collections to get the first result:
$nb = collect(DB::select('SELECT nb_seances_archivees() AS nb'))->first()->nb;
Or directly access the first object in the array:
$nb = DB::select('SELECT nb_seances_archivees() AS nb')[0]->nb;
If you want to pass parameters then you should do:
DB::select('SELECT nb_seances_archivees(?) AS nb', [$parameter]);

Doctrine2 query orderBy with specific values first

I am trying to apply several filters to one dql in Symfony using Doctrine. I want order it by several columns (although for the moment I am having problems just with one column) and I want show first values that matches with specific values. I will write a simple example to illustrate it about the result that I am searching:
col1 col1
---- -----
A B
B => A
C C
W W
I was searching information about how to make it but I am a bit confused due to that some people says that I can't do it directly, other people says that it is possible using case when or if/else. I tried to use case when but without success. The code that I am using is the following:
Updated code and error
$query = $this->createQueryBuilder('article')
->where('article.title LIKE :article')
->setParameter('title', '%'.$term.'%')
->addSelect('(CASE WHEN article.to = \'WOR\' THEN 1 ELSE 0 END) AS to')
->addOrderBy('article.to', 'ASC')
->getQuery();
And if I want set the "B" value as parameter, should I use setParameter after the addSelect?
Right now with the abovecode I am getting the following error:
Key "title" for array with keys "0, to" does not exist in result.html.twig at line 177.
Information related about how I call this method into my controller and pass it to twig template:
$prodMan = $this->get('app.article.manager');
$articles = $prodMan->getResults((string)"t", $page);
$limit = 50;
$maxPages = ceil($articles->count() / $limit);
$thisPage = $page;
return $this->render('result.html.twig', compact('categories', 'maxPages', 'thisPage', 'articles', 'images'));
And the twig template where I have the error:
<td><p>{{articles.title}}></p></td>
Result of {{ dump(articles) }}
Paginator {#475 ▼
-query: Query {#484 ▼
-_state: 2
-_dql: "SELECT article, (CASE WHEN article.to = 'WOR' THEN 1 ELSE 0 END) AS to FROM AppBundle\Entity\Article article WHERE article.title LIKE :title ORDER BY article.to ASC"
-_parserResult: null
-_firstResult: 0
-_maxResults: 50
-_queryCache: null
-_expireQueryCache: false
-_queryCacheTTL: null
-_useQueryCache: true
#parameters: ArrayCollection {#483 ▼
-elements: array:1 [▼
0 => Parameter {#480 ▼
-name: "title"
-value: "%t%"
-type: 2
}
]
}
#_resultSetMapping: null
#_em: EntityManager {#105 …10}
#_hints: []
#_hydrationMode: 1
#_queryCacheProfile: null
#_expireResultCache: false
#_hydrationCacheProfile: null
}
-fetchJoinCollection: true
-useOutputWalkers: null
-count: 143
}
I executed the same dql query without the case when (with that dql I haven't any problem), and I compare the dumps in Twig and the only difference that I see is that in the other dql I am getting #483 and #482 indexes instead of #484 and #480 respectly
And I can't var_dump any position of the array, but the array has the right number of results, although I can't check if results are sorted in the right way
I am stuck with this problem and if someone could lead me to the right answer I'd be very grateful!
I'm not sure if your query will work, but what if you change this line like so:
->addSelect('(CASE WHEN article.to = \'B\' THEN 1 ELSE 0 END) AS HIDDEN to')
Escaping the quote, or:
->addSelect("(CASE WHEN article.to = 'B' THEN 1 ELSE 0 END) AS HIDDEN to")
That way the B is in quote. Again, not sure about the query itself.
EDIT #2 - Based on dump of articles
Looks like the dump is still a query.
You need to get the results like so:
$articles = $query->getResult();
Then pass the articles to you twig and render it.
Normally done like so:
return $this->render('result.html.twig', array(
'articles' => $articles,
));
See if that works.
You might need changes, but the above code gives you some idea of what to do.

Get latest distinct value of a filed in Laravel

I want to query the latest + distinct name.
I got the distinct part to work, but they're not the latest.
I'm not sure how to do that in Laravel.
I’ve tried
$localDevices = Device::orderBy('created_at', 'desc')->groupBy('mac')->get();
$localDeviceName = [];
$i = 0;
foreach ($localDevices as $localDevice) {
foreach ($devices as $device) {
if($localDevice->mac == $device->device_mac ){
$localDeviceName[$i]['name'] = $localDevice->name;
$localDeviceName[$i]['mac'] = $device->device_mac;
$i++;
}
}
}
Database
I got
array:1 [▼
0 => array:3 [▼
"name" => "Apple Watch"
"img" => "/images/photos/devices/apple-watch.jpg"
"mac" => "080027E2FC7D"
]
]
I want it to show ps4 because it is the latest.
Try #2
tried update my
orderBy('created_at', 'desc') to orderBy('created_at', 'asc')
I got the same result.
Try #3
tried placing orderBy after groupBy
Device::groupBy('mac')->orderBy('created_at', 'desc')->get();
I got the same result.
Any hints / suggestions on that will much appreciated !
You are doing a groupBy on your mac value which isn't unique, your Apple watch and PS4 have the same mac, mysql first groups by then orders your grouped results. That's why you are always getting Apple watch.
What you want is to fetch the latest record from each group and for that you might write a Raw query, check this Retrieving the last record in each group

Categories