Twig showing keys also instead of only values - php

I am using Laravel 5.3 along with Twig templating engine (Not Blade). I am trying to generate a list of drop-down list in the form. Instead of showing just the values. It is showing the keys as well.
For example:
{"display_name":"Admin"}
In my view the code is
{{ form_select('roles', roles, input_get('role'), {id:'user_type',class:'form-control'}) }}
In the controller
public function create()
{
$roles = Role::all('display_name');
return view('users.user-add')->with(['roles' => $roles]);
}
What am I missing?

I would suggest you to create a helper for this so that there is no requirement for you to pass roles from every controller to every view. Create a helper function like this :
if(!function_exists('getRoles'))
{
function getRoles()
{
$roles = Role::get();
foreach ($roles as $role)
{
$results[$role->id] = $role->name;
}
return $results;
}
}
and now in your template do :
{{ form_select('roles', getRoles(), input_get('role'), {id:'user_type',class:'form-control'}) }}
I hope I understood your question as intended and this helps you achieve what you are looking for.

Related

unable to define relationship in laravel 5.7

I have two table as sbj_topics and difficulty_level_sbj_topic so, I want to define relationship b\w them to fetch records, so to make relationship I have done this,
SbjTopic.php:
public function difficulty_level_sbj_topic() {
return $this->hasMany('App\DiffiLvlSbjTopic');
}
And in DiffiLvlSbjTopic.php:
protected $table = 'difficulty_level_sbj_topic';
public function sbj_topics() {
return $this->belongsTo('App\SbjTopic');
}
After that I returned the data to a view as:
$easy = DiffiLvlSbjTopic::where(['subject_id' => $id, 'difficulty_level_id' => 2])->get();
return view('diffi_lvls.show', compact('easy'));
Then in the view I done this:
#foreach($easy as $easy)
{{ $easy->sbj_topics }}
#endforeach
but the page is blank, and when I do this {{ $easy->sbj_topics->sbj_topic_name }} trying to get property of undefined! comes.
The main purpose of creating relationship is to display Subject Topic Name because I have foreign key as sbj_topic_id in difficulty_level_sbj_topic table so if anyone has any other idea to do this without relationship that will be awesome.
Break this down:
SbjTopic - has many difflevels
a difflevel belongs to aSbjTopic
With this understanding, I can see you are getting the difflevels (DiffiLvlSbjTopic). This is actually what you are passing to your blade.
So first off: complete your relationship by specify the foreign keys. i.e:
In the SbjTopics model:
public function difficulty_level_sbj_topic() {
return $this->hasMany('App\DiffiLvlSbjTopic', 'subject_id');
}
with this, you know that in the 'difficulty_level_sbj_topic' you must have the column subject_id.
Now define the reverse relationship in your DiffiLvlSbjTopic model:
public function sbj_topics() {
return $this->belongsTo('App\SbjTopic', 'subject_id');
}
With all these in place in your controller or route all you need to do is fetch the DiffiLvlSbjTopic model properties. For instance:
public function index () {
$easy = DiffiLvlSbjTopic::all();
return view('diffi_lvls.show', compact('easy'));
}
Finally in your view:
#foreach($easy as $difflevel)
<div>{{ $difflevel->sbj_topics->name }} </div>
#endforeach
That's it.
Your both variables should not be $easy it can be something like $easy as $easySingle. And add a loop inside like
#foreach($easy as $easySingle)
foreach ($easySingle->sbj_topics as $topic) {
$topic->property;
}
#endforeach

undefined variable when trying to fetch data from database laravel

Hi I'm having trouble getting data from database after adding a new function inside my controller. Can anyone explain to me this error and what should I do?
Background information: I have 3 different type of tables, personal_infos, user_infos and user_info1s table where personal_infos hasMany user_infos and user_info1s. I am using user_id as a foreign key to link together with personal_infos table
I'm using this video as a reference and want to do something like his end result (see 17.17 of video), but I get this error:
Error: Undefined variable: data
What I want to do:
Route.php
Route::get('/home/{id}', 'HomeController#getData')->name('home');
HomeController
public function getData($id) {
$data['data'] = DB::table('personal_infos')->get()->sortByDesc('upload_time');
if (count($data) > 0) {
return view('home',$data)
->with('test', personal_info::find($id)); // --> after adding this got error
} else {
return view('home');
}
}
Home.blade.php
<table class="table table-bordered">
<tr>
<th><strong><big>Name: </big></strong></th>
</tr>
<td>
<tr>
#foreach($data as $value)
<tr>
<th>{{HTML::link_to_route('home',$value->Name, array($value->id)) }}</th>
</tr>
#endforeach
</tr>
</tr>
</table>
Code that I have now after some changes:
HomeController:
public function getData($id = null){
$data['data'] = DB::table('personal_infos')->orderBy('created_at', 'desc')->get();
return view('home')
->with('personalInfos', $personalInfos)
->with('test', personal_info::find($id));
}
}
home.blade.php
<ul>
#foreach ($personalInfos as $info)
<li>{{ HTML::link_to_route('home', $info->Name, [ $info->id ]) }}</li>
#endforeach
</ul>
Route
Route::get('/home/{id?}', 'HomeController#getData')->name('home');
personal_info model: (don't know if needed but just in case)
class personal_info extends Eloquent
{
protected $fillable = array('Email', 'Name', 'Mobile_No');
protected $table = 'personal_infos';
protected $primaryKey = 'id';
public function user_infos() {
return $this->hasMany('App\user_info','user_id');
}
public function user_info1s() {
return $this->hasMany('App\user_info1','user_id');
}
}
user_info1 and user_info (they are similar so I will just put 1 of them)
class user_info1 extends Eloquent
{
protected $fillable = array('hobby','sport','user_id');
public function personal_infos() {
return $this->belongsTo('App\personal_info', 'user_id', 'id');
}
}
I can tell you're learning Laravel. There are several issues with the code posted in your question. Let's walk through each of these to see if we can improve your understanding.
First, let's take a look at the controller method signature:
public function getData($id)
This method expects an $id parameter defined in the corresponding route. However, if we take a look at the route:
Route::get('/home/(:any)', 'HomeController#getData')->name('home');
...it doesn't properly declare that the URL contains a parameter (the video you're watching is about a very old version of Laravel). As described in the docs, we'll need to change the route signature to include a parameter for $id:
Route::get('/home/{id}', 'HomeController#getData')->name('home');
Next, let's see how the controller method fetches its data:
$data['data'] = DB::table('personal_infos')->get()->sortByDesc('upload_time');
This query fetches all records from personal_infos into a Collection, and then sorts them by upload_time. This is fine, but database engines can usually sort data faster than our PHP application, so we can instruct the DB to sort our data for us:
$data['data'] = DB::table('personal_infos')->orderBy('upload_time', 'desc')->get();
Notice how we changed the call to sortByDesc() on the collection to orderBy() for the database query. Now, the database sorts the results for us, so the collection doesn't need to.
Finally, let's try to fix the error you experience when passing the data to the view. Here's how your controller method currently does it:
if (count($data) > 0) {
return view('home', $data)
->with('test', personal_info::find($id)); // --> after adding this got error
} else {
return view('home');
}
There are a couple problems with the code above:
count($data) will always be greater than zero, because we're setting $data['data'] every time we call the method, so the else block will never execute. This is probably fine because...
...when count($data) equals zero, the controller doesn't pass the view any data, so $data in the view will be undefined.
The view in question uses #foreach to loop through each of the results, so we can simplify the code in the controller method because foreach won't iterate over an empty collection:
$personalInfos = DB::table('personal_infos')->orderBy('upload_time', 'desc')->get();
return view('home')
->with('personalInfos', $personalInfos)
->with('test', personal_info::find($id));
The view will receive two variables from the method above: $personalInfos and $test. I took the liberty of renaming $data['data'] into a more meaningful variable. This becomes very important as the project grows. Here's how we can use the data in the view:
<ul>
#foreach ($personalInfos as $info)
<li>{{ HTML::link_to_route('home', $info->Name, [ $info->id ]) }}</li>
#endforeach
</ul>
The template above outputs an unordered list as shown in the image in the question. The original table contains several row/column nesting errors and will not display the information like the question describes. As we can see, this template loops through each result in $personalInfos. If $personalInfos is empty, the list will not display any items.
If we want our controller method to handle the route with or without an ID, we'll need to tell Laravel that the ID is optional. For the route, a question mark (?) after the parameter makes it optional:
Route::get('/home/{id?}', 'HomeController#getData')->name('home');
Then, we can set a default value for the controller method that handles the route. In this case, we'll use null:
public function getData($id = null)
Of course, after we update this, we'll need to change the method to handle a null $id argument, which we use to fetch a personal_info for the view's $test variable. The question doesn't explain how the view uses $test, so I'll leave this as an exercise to the reader :)
Follow are two ways to pass multiple variables to view:
//Passing variable to view using with Method
return view('home')->with(['test'=>personal_info::find($id),'data'=>$data['data']]);
//Passing variable to view using Associative Array
return view('home', ['test'=>personal_info::find($id),'data'=>$data['data']]);

Laravel get record from database in blade view

I would like to known how to get data from database in blade like from User table:
{{ Auth::user()->name }}
I have table user_settings
I would like to get record from this table by logged user id like this:
{{ UserSettings::user()->my_field }}
How can I do that?
Try this on your blade view
{{ \App\UserSettings::where('user_id',Auth::user()->id)->first()->my_field }}
In default, model file is inside App folder.
Such direct access to database table is not preferred though, you can return this as a variable from controller function like,
$field = \App\UserSettings::where('user_id',Auth::user()->id)->first()->my_field;
return view('view_name',comapact('field'));
and use in blade like
{{$field}}
Another good way is posted by Orkhan in another answer using eloquent relationship.
Hope you understand.
You need to retrieve the UserSettings associated to the authenticated user:
UserSettings::where('user_id', Auth::id())->first()->my_field
You can defined a method named current() to return that for you.
class UserSettings extends Model
{
public static function current()
{
return UserSettings::where('user_id', Auth::id())->first()
}
}
Then use:
UserSettings::current()
On the other had it would better to use one-to-one relationship on user model:
class User extends Model
{
public function settings()
{
return $this->hasOne('App\UserSettings');
}
}
Then use:
Auth::user()->settings->my_field

Route with multiple Id's (Laravel 5.2)

I want a URI like this
http://localhost:8000/category/1/3
The first id is Category_id and second is Food_id.
My route is:
Route::get('category/{Category_id?}/{Food_id?}', 'DetailsController#categ');
And in Controller I have:
public function categ($Category_id,$Food_id)
{
$category = Categories::with('food')->findOrFail($Category_id);
$food = Food::with('restaurant','categories')->findOrFail($Food_id);
return view('category', compact('category','food'));
}
But it gives error Missing argument 2 for App\Http\Controllers\Detailscontroller::categ().Can anyone tell where is the problem.I am new to laravel.What I want to do is first shows food items based on category_id and then shows the deatails of foods according to food_id.
For showing relevant category of foods,in my view I have
#foreach ($Category as $categories)
{{$categories->CategoryName}}
#endforeach
and it shows me food items.Then I want when I click on any food item it shows me detail based on food_id. so my nxt view look like:
#foreach ($category->food as $food)
{{ $food->FoodName }}
#endforeach
The comment Anish left was correct, however, you main problem will come when you're trying to find models with null. To get around this you could have something like:
public function categ($Category_id,$Food_id)
{
$category = is_null($Category_id) ? []: Categories::with('food')->findOrFail($Category_id);
$food = is_null($Food_id) ? [] : Food::with('restaurant','categories')->findOrFail($Food_id);
return view('category', compact('category','food'));
}
NB They may be more errors in your view file depending on if you're trying to access.
However, I would go with a much more RESTful approach: https://laravel.com/docs/5.2/controllers#restful-resource-controllers
Essentially, this would mean having a controller for you Categories:
public function index() {
//Code to get all categories (if you have a lot you may want to paginate them)
}
public function show($Category_Id) {
$category = Categories::with('food')->findOrFail($Category_id);
//etc
}
and then a controller for you Foods with just a show() method:
public function show($Food_Id) {
$food = Food::with('restaurant','categories')->findOrFail($Food_id);
}
OR depending on how you set your route up you could also include the category as well if you need to (but if it's just a one2Many relationship it might be redundant) so you would have
public function show($category_ID, $Food_Id) //etc
Your routes would then be set up like this:
Route::get('categories', 'CategoriesController#index');
Route::get('categories/{$category_id}', 'CategoriesController#show');
//Assuming you go with the first option - something like:
Route::get('foods/{$food_id}', 'FoodsController#show');
//Assuming you go with the section option for Foods
Route::get('categories/{$category_id}/{$food_id}', 'FoodsController#show');
Obviously, the above is just an example so feel free to set you controllers/routes up how you like.
If you do end up going down the RESTful route (recommended) you then might want to look at: https://laravel.com/docs/5.2/routing#route-model-binding
Hope this help!

Laravel get relationship or all objects

I'm using Laravel 5.2. In my application, if a user is an admin, he can see all groups. Otherwise, he can only see his groups.
Model
public function groups() {
if ($this->isAdmin()) {
return \App\Group::get();
}
return $this->belongsToMany('App\Group');
}
View
#foreach($user->groups as $group)
{{ $group->name }}
#endforeach
Result
The code above works if the user is not an admin, but I get this error if the user is an admin
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
I tried this instead: $user->groups() as $group, it works when the user is an admin, but show nothing when it's not an admin.
Question
I know when I call a relation as a property ($user->groups), it returns a collection of objects. Instead, if I call it as a function ($user->groups()), I get a QueryBuilder instance.
What can I do to use the same syntax as in my view ?
Note: I cannot add all groups in the database to the admin, as admins must have no group.
The way is not using directly relationship for this but using extra method to handle this.
First in your model create simple relationship:
public function groups()
{
return $this->belongsToMany('App\Group');
}
and then create extra method:
public function availableGroups()
{
if ($this->isAdmin()) {
return \App\Group::get();
}
return $this->groups;
}
Now in view you can use:
#foreach($user->availableGroups() as $group)
{{ $group->name }}
#endforeach

Categories