laravel collection group by then order by - php

maybe trivial but i'm stuck on this.
$questions = FaqQuestion::with('category')->get()->groupBy('faq_categories_id')->sortBy('sortorder');
The result is grouped by faq_categories_id, and sorted by FaqQuestion id it seems. I want to orderBy the 'sortorder' field ASC from FaqQuestion, the same column name exists in category.
Any input is appreciated. Thanks
edit:
$questions returns a collection:
Illuminate\Database\Eloquent\Collection {#1309 ▼
#items: array:3 [▼
1 => Illuminate\Database\Eloquent\Collection {#1154 ▼
#items: array:3 [▼
0 => App\FaqQuestion {#1385 ▼
+table: "faq_questions"
#dates: array:4 [▶]
#fillable: array:6 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:10 [▶]
#original: array:10 [▶]
#changes: []
#casts: []
#classCastCache: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
1 => App\FaqQuestion {#1387 ▶}
2 => App\FaqQuestion {#1388 ▶}
]
}
2 => Illuminate\Database\Eloquent\Collection {#430 ▶}
3 => Illuminate\Database\Eloquent\Collection {#431 ▶}
]
}

Related

Paginator data don't show well in livewire "public property [posts] must be of type: [numeric, string, array, null, or boolean]"

I like to use livewire instead of controller
public function index()
{
return view('advert.index', [
'posts' => Advert::latest()->filter(
request(['search', 'category', 'author'])
)->paginate(18)->withQueryString()
]);
}
in livewire <livewire:advert.home :querys="request(['search', 'category', 'author'])">
public function mount($querys)
{
$this->querys = $querys;
}
public function render()
{
$this->posts = Advert::latest()->filter([$this->querys])->paginate($this->perPage)->withQueryString();
}
but nothing work
it is mostly say
Livewire component's [advert.home] public property [posts] must be of
type: [numeric, string, array, null, or boolean]. Only protected or
private properties can be set as other types because JavaScript
doesn't need to access them.
I am lost i use this but it don't work well and show error above. and look same data passed to livewire component.
and there is no difference between livewire $this->posts and 'posts' from controller i can't figure about that.
like
'posts' dd($posts) from controller
Illuminate\Pagination\LengthAwarePaginator {#1412 ▼
#total: 2
#lastPage: 1
#items: Illuminate\Database\Eloquent\Collection {#1402 ▼
#items: array:2 [▼
0 => App\Models\Advert {#1409 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => App\Models\Advert {#1410 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
#perPage: 18
#currentPage: 1
#path: "https://awento.ddns.net/search"
#query: []
#fragment: null
#pageName: "page"
+onEachSide: 3
#options: array:2 [▶]
}
and livewire $this->posts
ddd($posts)
Illuminate\Pagination\LengthAwarePaginator {#1470 ▼
#total: 2
#lastPage: 1
#items: Illuminate\Database\Eloquent\Collection {#1458 ▼
#items: array:2 [▼
0 => App\Models\Advert {#1465 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => App\Models\Advert {#1467 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
#perPage: 15
#currentPage: 1
#path: "https://awento.ddns.net"
#query: []
#fragment: null
#pageName: "page"
+onEachSide: 3
#options: array:2 [▶]
}
After some trail and error i realise the issue is with whole data if we arrange in some form of data that there will be no issue. So Now i create a array for transfer data with some foreach. If there is another better way please let me know.
$postss = Advert::latest()->filter($this->querys)->paginate($this->perPage)->withQueryString();
$posts = array();
foreach($postss as $post)
{
array_push($posts, $post);
}
$this->posts = $posts;
It seem paginate don't work in livewire using limit now.

get one unique item from a laravel relationship

i have a 1 to n relation ship between product and images and on images i have a field called color_id which has a 1 to n with images . now what i want to do is to call the product with images relationship like below :
$relation = Product::with('images')->where('id',$product->id)->get();
dd($relation);
now what want is to get 1 images from each color_id so for example if this product has 3 images with color_id of 1 , and 4 images with color_id of 2 .i want to get 1 images from each color . and here is the dd result of $relation in case needed .
^ Illuminate\Database\Eloquent\Collection {#945 ▼
#items: array:1 [▼
0 => Webkul\Product\Models\Product {#912 ▼
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:7 [▶]
#original: array:7 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"images" => Illuminate\Database\Eloquent\Collection {#968 ▼
#items: array:3 [▼
0 => Webkul\Product\Models\ProductImage {#967 ▼
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▼
"id" => 17
"type" => null
"path" => "product/39/y0ueAFEgscD9ZsVFg7nT2WPNsU6vDyXWqLVONa8L.jpeg"
"product_id" => 39
"product_color_id" => 3
"product_size_id" => null
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => Webkul\Product\Models\ProductImage {#970 ▼
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▼
"id" => 23
"type" => null
"path" => "product/39/M9JTVsy2BtNp8LuUQh7cp17S5jN1ifOZ1P9WZk3h.jpeg"
"product_id" => 39
"product_color_id" => 2
"product_size_id" => null
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
2 => Webkul\Product\Models\ProductImage {#969 ▼
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▼
"id" => 24
"type" => null
"path" => "product/39/STA9sGKjWHWDn0wkmnVRqZYdI2adLE5qaIn7vyFQ.jpeg"
"product_id" => 39
"product_color_id" => 1
"product_size_id" => null
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
Try this
$relation =Product::with(array('images' => function($query) {
$query->groupBy('product_color_id');
})->where('id',$product->id)->get();

Laravel, cant' get property of colletion

I have Collection form my Form obj, and iam trying to get all pages belongs to that form,
when I do $survey = Forms::find(68)->with('pages')->get(); Iam getting this:
Illuminate\Database\Eloquent\Collection {#522 ▼
#items: array:18 [▼
0 => App\Models\Forms {#562 ▼
#table: "forms"
#fillable: array:4 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:9 [▶]
#original: array:9 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"pages" => Illuminate\Database\Eloquent\Collection {#596 ▼
#items: array:5 [▼
0 => App\Models\Pages {#628 ▶}
1 => App\Models\Pages {#632 ▶}
2 => App\Models\Pages {#633 ▶}
3 => App\Models\Pages {#634 ▶}
4 => App\Models\Pages {#635 ▶}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
but can't get property of relations, when I do $form->pages Iam getting null
Its works fine for other property like questions (same relations)
here is my model:
class Forms extends Model
{
protected $table = "forms";
protected $fillable = array('name', 'description', 'status', 'token');
public function pages()
{
return $this->hasMany('App\Models\Pages');
}
public function questions()
{
return $this->hasMany('App\Models\Question');
}
}
class Pages extends Model
{
protected $table = "pages";
public $timestamps = false;
protected $fillable = array('name', 'description' ,'priority', 'token');
public function form()
{
return $this->belongsTo('App\Models\Forms');
}
}
and finally, method where Iam trying to get results:
public function index()
{
$survey = Forms::with('pages')->find(68);//Did update regarding to sugestion
dd($survey);
return view("pages.surveys", compact('survey'));
}
Thanks for any help.
Greg
I think you should reverse the order of the with() and find() functions.
$survey = Forms::with('pages')->find(68);
Note that find() actually executes the query, therefore you don't have to use get() again. As a rule of thumb: if you need to get only one result out of your query you should use first() or find() (the latter could also be used to retrieve collections), otherwise use all() or get() to fetch a collection of results.
$form = Forms::find(68);
dd($form->pages);
OR
$form = Form::find(68)->pages->get(); //It will return all the pages having relation
try this, It will first find form having id '68' then as per relation given it will fetch the records
Seems almost of your codes are okay. This might be a problem only with your foreign key. In your pages relationship in your forms, laravel will expect a foreign key in your pages table namely 'form_id' or 'forms_id' since you are not passing a second argument in your pages relationship. Make sure that in your pages migration your foreign key is set to to form_id also
when i do dd($survey);
App\Models\Forms {#513 ▼
#table: "forms"
#fillable: array:4 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:9 [▶]
#original: array:9 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"pages" => Illuminate\Database\Eloquent\Collection {#521 ▼
#items: array:6 [▼
0 => App\Models\Pages {#552 ▼
#table: "pages"
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => App\Models\Pages {#553 ▶}
2 => App\Models\Pages {#554 ▶}
3 => App\Models\Pages {#555 ▶}
4 => App\Models\Pages {#556 ▶}
5 => App\Models\Pages {#557 ▶}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}

Checking if a value exists in two or more arrays in php

Hi there I have this problem here:
I have this on my controller:
$questions = Question::select('text','question_image','question_type_id','id')
->whereIn('id', $question_ids)
->where('deleted', 0)
->orderBy('created_at','ASC')
->paginate(20);
which ouputs this:
LengthAwarePaginator {#1635 ▼
#total: 4
#lastPage: 1
#items: Collection {#1627 ▼
#items: array:4 [▼
0 => Question {#1622 ▼
#hidden: array:1 [▶]
#fillable: array:10 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:4 [▼
"text" => "asd"
"question_image" => null
"question_type_id" => 5
"id" => 1213
]
#original: array:4 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#visible: []
#guarded: array:1 [▶]
}
1 => Question {#1623 ▶}
2 => Question {#1624 ▶}
3 => Question {#1625 ▶}
And then I have this one:
$owner_questions = BankQuestion::select('question_id')->where('bank_id', $bank_id)->where('user_id', $auth)->where('deleted', 0)->get()->toArray();
Which outputs this:
array:2 [▼
0 => array:1 [▼
"question_id" => 1217
]
1 => array:1 [▼
"question_id" => 1218
]
]
And here I have my loop of questions:
foreach ($questions as $question) {
if(in_array($question->id, $owner_questions )){
$question->authorQuestion = 1;
}else{
$question->authorQuestion = 0;
}
}
Here I need to find the $question->id that exists on $owner_questions arrays which there the numbers that I am looking for are 1217 and 1218. Can someone please help me what I am doing wrong here please..?
You are comparing numeric value($question->id) with an array, which has a property question_id. Here is what you can do:
$owner_questions_ids = array();
foreach($owner_questions as $owner_question){
$owner_questions_ids[] = $owner_question['question_id'];
}
// now you can compare them
in_array($question->id, $owner_questions_ids )

Array of objects , that won't loop in a foreach in laravel

I'm not sure this is really a laravel question but, when I dd(die and dump) this dd($user->friends()); I get the following. I did notice that it is a collection. I'm not sure if that means something different or not. But it still should be an array of items I believe. With the first user at the [0] mark and next [1], etc...
Collection {#184 ▼
#items: array:2 [▼
0 => User {#189 ▼
#table: "users"
#fillable: array:7 [▶]
#hidden: array:3 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:11 [▶]
#original: array:13 [▶]
#relations: array:1 [▶]
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
1 => User {#190 ▼
#table: "users"
#fillable: array:7 [▶]
#hidden: array:3 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:11 [▶]
#original: array:13 [▶]
#relations: array:1 [▶]
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
]
}
So then when I try to do something like :
foreach($user->friends() as $friend) {
dd($friend);
}
This is what I get after doing that:
User {#189 ▼
#table: "users"
#fillable: array:7 [▶]
#hidden: array:3 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:11 [▶]
#original: array:13 [▶]
#relations: array:1 [▶]
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
I want it to loop through all the users not just the first one. Is there a reason it is doing this. Am I doing the foreach wrong or does it have something to do with the collection?
When you do your foreach, you're only seeing one entry because of the dd(). Remember, it is "dump and die", so on the very first iteration, you're dumping the record and then dying.
Try this out:
foreach($user->friends() as $friend) {
print_r($friend);
}
If you just want to treat it as an array, use toArray on the collection first. Eg:
$friends = $user->friends()->toArray();
foreach($friends as $friend){
...some stuff...
}
Otherwise, use the features of the laravel collection as per the docs here:
http://laravel.com/docs/5.2/collections

Categories