How to pluck data for a form - laravel

I'd like to show names on my select dropdown
I have 3 tables: 'users','users_pro' and 'practice'
users : id ,name ,dob ,.. etc
users_pro : id ,user_id,..etc
practice : id , user_pro_id ,...etc
I want to input data to table 'practice' and I want to make a select dropdown using pluck on users_pro with users like this :
public function input_practice()
{
$data= Users_pro::with('users')->get()->pluck('id','user_id');
dd($data);
// return view('admin.input.input_riwayat_kgb',
// [
// 'data'=>$data,
// ]);
}
If I dd($data), I get :
Collection {#327 ▼
#items: array:4 [▼
6 => 3 // 6 is user_id ,and 3 is 'id' on users_pro , i need to show 'name' like 3 => 'jhon'
13 => 4
12 => 5
14 => 6
]
}
But I want to show the name of the user on my select dropdown. Can someone help me?

You are trying to pull a collection and then get the name and id from the relationship models within. Thus, you will get an error that the property does not exist on the collection because it is many User_pro objects and then tries to get user data from each one of the relations would require a loop.
Assuming you have a users relationship set up on the User_pro model, you can get your dropdown list like this:
$data= User::whereHas('user_pro')->pluck('name','id');
This gives you a collection of users (who happen to be pros) and then plucks the name and id of your users for you to use in your dropdown.

This is solved with this line :
$data = Users_pro::with('users')->get()->pluck('users.nama', 'id');

Related

How do I get the model instance inline with the main Eloquent query by foreign key reference

My question is simple.
I have 2 tables. "Users" and "Access Levels".
The Access Levels table contains the names of the available levels on the site. Something like this:
Access Level Table
id
name
1
admin
2
subscriber
And in the Users table, I'm using the access_level through foreign key. Something like this:
Users Table
id
username
access_level
1
user1
1
2
user2
2
3
user3
2
Now I'm querying all the user in usercontroller with User:all(). The results return a collection which includes the access_level id as expected. But I want to include the name of the associated access_level within the same result set/collection. I've tried searching for Eloquent relationships, but I'm not able to understand the concept.
This is the result that I'm expecting:
Array(
[id => 1,username => user1, access_level => admin],
[id => 2,username => user2, access_level => subscriber],
[id => 3,username => user3, access_level => subscriber],
)
EDIT
After applying the code as suggested by #xenooo, I see that it returns the results with a "relations" key which has the foreign_key model instance. I've done your implementation on another set of tables. This time, in place of users, its books. And category in place of access_level. This is the response that I get with dd(). I've used the following code,
$books = Book::with('category')->find(1);
dd($books);
dd of response
First you must define the relationship of your database to your model. Assuming that you have a model for AccessLevel :
// app/Models/AccessLevel.php
public function users() : HasMany
{
return $this->hasMany(User::class, 'access_level');
}
// app/Models/User.php
public function accessLevel() : BelongsTo
{
return $this->belongsTo(AccessLevel::class,'access_level');
}
To include the relationship when querying.
User::with('accessLevel')->get(); // accessLevel is the name of the function you define.

Sort an Eloquent model

Table for MyModel is like below
id name parent_id
--------------------------
1 parent1 null
2 p1-c1 1
3 parent2 null
4 p1-c1-g1 2
5 p2-c1 3
6 p1-c1-g1-f1 4
7 parent3 null
8 p1-c2 1
9 p3-c1 7
10 p1-c2-c1 8
How order with eloquent or raw DB query without getting all rows like below
Collection {#499 ▼
#items: array:22 [▼
0 => MyModel {#524 ▶} // parent1
1 => MyModel {#525 ▶} // p1-c1
2 => MyModel {#526 ▶} // p1-c1-g1
3 => MyModel {#527 ▶} // p1-c1-g1-f1
4 => MyModel {#528 ▶} // p1-c2
5 => MyModel {#529 ▶} // p1-c2-c1
6 => MyModel {#530 ▶} // parent2
7 => MyModel {#531 ▶} // p2-c1
8 => MyModel {#532 ▶} // parent3
9 => MyModel {#533 ▶} // p3-c1
]
}
for a better view and understanding
parent1
p1-c1
p1-c1-g1
p1-c1-g1-f1
p1-c2
p1-c2-c1
parent2
p2-c1
parent3
p3-c1
use Recursive relationship to same table
For example if model name is MyModel then the relationship will be
public function child(){
return $this->hasMany(MyModel::class,'parent_id','id');
}
public function recursiveChild(){
return $this->child()->with('recursiveChild');
}
So in your controller
MyModel::with(['recursiveChild'])->get();
What is your actual code, what are you trying to accomplish with this?
Collections are your friend in Laravel.
You can do a groupBy or using a With if you have a table that's related... your question is really too ambiguous.
You can get fairly complex with many chained Where orWhere with limits and groupBy
What I do see is that you need to have is not only the parent in the db but you also need a sort order on the children. Another thought is do you need a Grandparent, Parent, child? In that case you're going to have to have columns for all of those to know who they belong to when building your collection or doing just a straight eloquent pull.
My guess is this is for a menu or something you have here. Again ambiguity, so totally guessing.
EDIT
I've done this kind of thing in several apps...
You're table is going to look something like this:
id, name, menu_type, url, page_id, parent_id, sidebar, order, depth, role, created_at, updated_at, deleted_at
So in your model your going to want to do a relationship:
public function parent()
{
return $this->belongsTo('App\Models\Menus', 'parent_id');
}
public function children()
{
return $this->hasMany('App\Models\Menus', 'parent_id')->orderBy('order', 'asc');
}
Then what I've done is use this as a trait so it's available wherever I need to use it.
The trait is a little more complex than you are asking but it points you in the direction.
public function PrimaryMenu($pageid , $namespace, $user) {
// Get all primary menu items.
$appspace = "\App\Models\\".$namespace."\\Menus";
$roles = $user->roles->pluck('name');
$pmenus = $appspace::with('children')->where([['menu_type', '=', 'primary'],['parent_id','=', NULL]])->
where(function ($q) use($pageid) {
$q->where('page_id', '=', $pageid)->orWhere('page_id', NULL);
})->
where(function ($q2) use($roles) {
$q2->whereIn('role', $roles)->orWhere('role', '=', NULL);
})->
get();
return $pmenus;
}
You can see I'm checking a type of menu (this can be anything as long as you have something to group them by category) in this case primary, then I check for the page and see if we should include a row or not on the page then I check for any roles the user might have that we should include items.
Then in your controller it's just a matter of using the trait at the top:
use App\Traits\CommonTrait;
Now all of those traits are available to use in your controller. So you just call the function you need:
$pmenus = $this->PrimaryMenu($pageid, $namespace, $user);
You can see I'm sending along 3 variables to this as I have this set up for having many menus. Really the code translates to anything though that you want children associated with a parent.
The important bits are the model actions on relationships.
Thanks everyone, i used this package to achieve a sort like that.
https://github.com/lazychaser/laravel-nestedset#building-flat-tree

How do I return the ID field in a related table in Laravel request

I have two related tables and I want to return all fields including the ID (key) field. My query below returns all fields except the ID. how do I return the ID field from one of the tables?
'programmes' => ProgrammeInstances::with('programmes')->get(),
the query below returns Unknown column 'programmes.programme_title' as it is looking for it in the table 'programme_instances'
'programmes' => ProgrammeInstances::with('programmes')->select('programmes.programme_title', 'programmeInstances.id', 'programmeInstances.name', 'programmeInstances.year')->get(),
Laravel provides multiple relationships, one of these is the hasMany() relationship which should return a collection where a User hasMany rows inside of your database
For example, inside your User model :
public function programmes() {
return $this->hasMany(Program::class);
}
Now in your controller, you can do :
public function edit($id) {
$programmes = User::find($id)->with('programmes')->get();
return view('user.edit')->with('programmes', $programmes);
}
And then you can loop over it inside your view
#forelse($programmes->programmes as $program)
// provide the data
#empty
// the user doesn’t have any programmes
#endforelse
a solution i found below - still not sure why ID isnt automatically returned when i get all fields, but works when i specify individual fields:
'programmes' => ProgrammeInstances::with('programmes')
->get()
->transform(fn ($prog) => [
'programme_title' => $prog->programmes->programme_title,
'id' => $prog->id,
'name' => $prog->name,
'year' => $prog->year,
]),

Cannot using where in eloquent

I'm using Eloquent ORM in Laravel. There is 2 model, User and Trans. User hasMany Trans, and Trans belongsTo User. The problem is when I'm using query where, it doesn't work.
I tried using ->get() in the last code, it still doesn't work. I tried using ->all() in the last code it still doesn't work. I tried whereIn, it still doesn't work.
User Model
public function trans()
{
return $this->hasMany('App\Trans', 'user_id');
}
Trans Model
public function user ()
{
return $this->belongsTo('App\User','user_id');
}
Controller
$trans = Auth::user()->trans->where('date', $date);
I want the output is based on query where the date is based on user input, when I delete ->where , it works and the output like this.
Collection {#797 ▼
#items: array:13 [▼
0 => Trans {#783 ▶}
1 => Trans {#784 ▶}
2 => Trans {#785 ▶}
3 => Trans {#786 ▶}
]
}
try to change like that
Auth::user()->trans->where('date', $date);
to
Auth::user()->trans()->where('date', $date)->get();
note : if you want to get only property then u get property without
pointer but if you want to used another method then must used(add)
pointer(->).

Laravel 5: Build dynamic query for Eloquent Model and pass to view

I have just started to learn Laravel 5, so I hope my question is not too stupid. I am trying to achieve the following. I have 3 tables
adverts
categories
advert_category
In my categories table I have main and subcategories. So parent categories have got parent_id NULL otherwise they show the id of the parent. When I save a new advert, I have the advert_id and the category_id saved in the pivot table advert_category. All that works fine. I am now trying the following. I want a Navigation with Maincategories and Subcategories shown. When I click on a Subcategory then I can read out easily the advert_id's from the advert_category table, because I am only looking for only 1 category_id, but I now plan to be able to click on the Maincategory and now show all the Adverts which belong to all the Subcategories from this Maincategory. So my approach is the following:
// Look up if passed id is found under parent_id column
$cat = Category::where('parent_id', $id)->get();
// The choosen category is a maincategory,
// therefore build dynamic where to look for all the id's
if (count($cat) > 0)
{
$query = Category::select();
foreach($cat as $value)
{
$query->orWhere('id', '=', $value->id);
}
$advertList = $query->get();
}
else{
$advertList = Category::findOrFail($id);
}
return view ('publicpage.adverts.showall',['advertList' => $advertList->adverts]);
Unfortunately, when I go on the Maincategory, I get below error. When I go on the Subcategory, I get the adverts shown.
Undefined property: Illuminate\Database\Eloquent\Collection::$adverts
A dd($advertlist) brings the following result:
Clicked on Maincategory:
Collection {#203 ▼
#items: array:2 [▼
0 => Category {#204 ▶}
1 => Category {#205 ▶}
] }
So it shows Collection.
Clicked on Subcategory
Category {#201 ▼
#table: "Categories"
#connection: null
I can see that there is obviously a difference, but I have got no idea, how to fix that or what the best approach would be. I hope I explained it well enough to understand my task and look forward to any advice. Thanks in advance !
UPDATE
After the below comment, I tried it out:
// Look up if passed id is found under parent_id column
$cat = Category::where('parent_id', $id)->get();
if (count($cat) > 0)
{
$query = Category::select();
foreach($cat as $value)
{
$query->orWhere('id', '=', $value->id);
}
$advertList = $query->get();
return view ('frontend.adverts.showall',['advertList' => $advertList[0]->adverts]);
}
else{
// 1 Category,
$advertList = Category::findOrFail($id);
return view ('frontend.adverts.showall',['advertList' => $advertList->adverts]);
}
This way I get the adverts for the first category, but how would I manage to hand over the adverts for all the categories or how can I handle this? I just don't seem to to be able to fix this problem. Or would the change be in the view? I tried it with another foreach in the view aswell to run through the adervertList, but again no success. Any advice? Thank you very much in advance!
tl;dr
The problem is here, that you are using $advertList->adverts and $advertList might be in some cases collection (you can think it as it was some kind of array).
So you cannot simply write $array->adverts but you should do something like this $array[0]->adverts in case you want to get adverts for 1st element only.

Resources