How to return name of table of grade when save like json? - laravel-5.8

I have two tables, users and grades.
users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
$table->string('grade_id')->nullable();
}
}
grades table
public function up()
{
Schema::create('grades', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
I save id of grade with json_encode,
I save in field like this
$user->grade_id = json_encode($request->input('grade_id'));
I want to return the grade name but I did not solve my problem
Controller
public function index()
{
$grades = Grade::all();
return view('index', compact('grades');
}
User.php
public function grade()
{
return $this->belongsTo(Grade::class);
}
index.blade.php
#if(isset(auth()->user()->grade_id) && !empty(auth()->user()->grade_id))
<?php
$grade = json_decode(auth()->user()->grade->name, true);
#foreach($grade as $key=>$item)
<li>
<div class="grade">{{ $grade[$key] }}</div>
</li>
#endforeach
?>
#endif
I get this errpr
Trying to get property of non-object

Bad answer
You save an array of ids in the users table. Then when you do $grade = json_decode(auth()->user()->grade->name) you get something you don't want to have. Indeed, the value of auth()->user()->grade is ["8", "8"], this is not a grade model. Now you should understand why this $grade = json_decode(auth()->user()->grade->name) fail: you're trying to get name property of a non object (as user()->grade is just an array).
To solve it badly (read the next part of my answer) you can just do this in your controller (you shouldn't do any <?php ?> in your view files):
public function index()
{
$grades_ids = json_decode(auth()->user()->grade); // ["8", "8"]
$grades = Grade::whereIn('id', $grades_ids)->get(); // Eloquent collection
return view('index', compact('grades');
}
And use it in your view:
#if($grades->count())
<ul>
#foreach($grades as $grade)
<li>
<div class="grade">{{ $grade->id }}</div>
</li>
#endforeach
</ul>
#endif
Good answer
Here you have a typical many to many relationships. A grade can have multiple users, and a user can have multiple grades. Then you should think of using a pivot table rather than a encoding several grade_id in json.
Create a users table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
}
}
Then you create your grades table:
public function up()
{
Schema::create('grades', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
Then you create the new user_grade_table:
public function up()
{
Schema::create('user_grade', function (Blueprint $table) {
$table->primary(['user_id', 'grade_id']);
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('grade_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('grade_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::table('user_grade', function (Blueprint $table) {
$table->dropPrimary('user_grade_user_id_grade_id_primary');
$table->dropForeign('user_grade_user_id_foreign');
$table->dropForeign('user_grade_grade_id_foreign');
});
Schema::dropIfExists('user_grade');
}
Don't forget to run the migrations. When this is done, you have to update your models, adding the belongs to many on both models.
User model
public function grades()
{
return $this->belongsToMany(Grade::class, 'user_grade', 'user_id', 'grade_id');
}
Same for grade model:
public function users()
{
return $this->belongsToMany(User::class, 'user_grade', 'grade_id', 'user_id');
}
Finally you can use it in your blade file:
#if($grades = auth()->user()->grades)
<ul>
#foreach($grades as $grade)
<li>
<div class="grade">{{ $grade->name }}</div>
</li>
#endforeach
</ul>
#endif

Related

i am trying to get the name using a relationship

here what I am trying to get the name of the category by using a relationship
here so far what I have done is I have defined a relationship in my product model as such
Public function category()
{
return $this->belongsto(Category::class);
}
I have also stored the field category id
in my products table
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('Category_id');
$table->string('name');
$table->string('code');
$table->string('color');
$table->string('description');
$table->double('price');
$table->integer('quantity');
$table->string('image');
$table->timestamps();
});
also I have defined a relationship in my Category model such as
public function product()
{
return $this->hasmany(Product::class);
}
ALSO I HAVE DEFINED Relationship IN
PRODUCT AS
Public function category()
{
return $this->belongsto(Category::class);
}
in my view I am trying to get the name of the category
#foreach($products as $pro)
<tr>
<td><img src="{{asset('uploads/maj/'.$pro->image)}}" class="img-circle" alt="User Image" width="50" height="50"> </td>
<td>{{$pro->category->name}}</td>
<td>{{$pro->name}}</td>
<td>{{$pro->code}}</td>
<td>{{$pro->color}}</td>
<td>{{$pro->description}}</td>
<td>{{$pro->price}}</td>
<td>{{$pro->quantity}}</td>
I am receiving the error
Trying to get property 'name' of non-object
how can I get the name of the category ??
I am trying to get it like this but this is giving error
{{$pro->category->name}}
the category table row
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->String('Parent_id');
$table->string('name');
$table->string('status');
$table->timestamps();
});
my laravel version is 7 thanks
Maybe one or more product doesn't have category or category_id is wrong.
you can use condition to check if category is not exist:
{{$pro->category ? $pro->category->name : "no category"}}
or can simply using null coalescing operator:
{{$pro->category->name ?? "no category"}}
if category is required you should prevent it by add table relation/foreign.
try this
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->foreignId('category_id')->nullable()->constrained()->onDelete('cascade');
$table->string('name');
$table->string('code');
$table->string('color');
$table->string('description');
$table->double('price');
$table->integer('quantity');
$table->string('image');
$table->timestamps();
});
in model Product
public function category(){
return $this->belongsTo(Category::class,'category_id','id');
}
thin call products
$products = product::orderBy('created_at','asc')->with('category')->get();
you can chick if has relationship or not
#if(! empty($pro->category)) {{ $pro->category->name }} #else <span>no category</span> #endif
You should try like this way :
(!empty($pro->category)) ? $pro->category->name : 'No category found'
I think You should define foreign key properly because your category_id not follow the coding standard. if you Category Model are in App directory you can use pass namespace like this
Public function category()
{
return $this->belongsto('App\Category','Category_id','id');
}
other wise :
Public function category()
{
return $this->belongsto('App\Models\Category','Category_id','id');
}

Retriving All Polymorphic Relations in Laravel

I've created polymorphic relations in my project. when i want to retrieve them like below
return view('category.index')->with('categories', Category::all()) ;
It returns the relations when i dd() them. However when I want to access the relation in view
when i call it in view it gives me the following result
{"id":1,"image":"abc\/abc.jpg","imageable_id":6,"imageable_type":"App\\Category","created_at":"2020-07-24T13:37:29.000000Z","updated_at":"2020-07-24T13:37:29.000000Z"}
but when i want to access the id or image index it says
Trying to get property 'id' of non-object (View:
D:\WaheedSindhani\Projects\Menu\menu_proj\resources\
views\category\index.blade.php)
i am not picking it up what is happening here
#if(isset($categories))
#foreach($categories as $category)
<tr>
<th scope="row">{{$loop->index+1}}</th>
<td>{{$category->name}}</td>
<td>{{$category->images->image}}</td>
</tr>
#endforeach
#endif
It says no attribute named image found.
Migration are as below
Images Table
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('image');
$table->unsignedInteger('imageable_id');
$table->string('imageable_type');
$table->timestamps();
});
}
Menus Table
public function up()
{
Schema::create('menus', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->boolean('visible');
$table->integer('priority');
$table->timestamps();
});
}
Categories Table
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->boolean('visibility');
$table->integer('priority');
$table->timestamps();
});
}
Models are as follow
class Menu extends Model
{
public function images()
{
return $this->morphMany( 'App\Image', 'imageable');
}
}
class Image extends Model
{
protected $guarded = [];
public function imageable(){
return $this->morphTo();
}
}
class Category extends Model
{
protected $guarded = [];
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
your problem occurs because the category->images is a Collection of images, not a single image. Because your relation is one to many, not one to one relationship so the soultion would be to loop over the images using a each loop and then do your work there.
that is why you are getting the error that you are trying to access a prop on a non-object.
#if(isset($categories))
#foreach($categories as $category)
<tr>
<th scope="row">{{$loop->index+1}}</th>
<td>{{$category->name}}</td>
#foreach($category->images as $image)
<td>{$image->name}</td>
#endforeach
</tr>
#endforeach
#endif
and this concept is true for every relationship that has a Many in them, hasMany, belongsToMany, etc...

Why my relation in laravel 5.8 not working?

Look at my codes and demo.
I have three tables categories and knowledge_rooms and category_knowledge_room. And all their data is stored.
categories table
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name_fa');
$table->string('name_en');
$table->integer('parent_id');
$table->string('icon')->nullable();
$table->timestamps();
});
}
knowledge_rooms table
public function up()
{
Schema::create('knowledge_rooms', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->string('lang');
$table->text('body');
$table->string('image');
$table->string('slug');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
Schema::create('category_knowledge_room', function (Blueprint $table) {
$table->bigInteger('category_id')->unsigned();
$table->bigInteger('knowledge_room_id')->unsigned();
$table->primary(['category_id', 'knowledge_room_id']);
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->foreign('knowledge_room_id')->references('id')->on('knowledge_rooms')->onDelete('cascade');
});
}
AppServiceProvider.php
public function register()
{
Schema::defaultStringLength(191);
view()->composer('*', function($view) {
$view->with('menus', Category::whereParent_id('0')->get());
});
}
Category.php
public function knowledgeRooms()
{
return $this->belongsToMany(KnowledgeRoom::class);
}
master.blade.php
#foreach($menus as $menu)
#foreach($menu->getChild as $submenu)
#foreach($submenu->knowledgeRooms as $knowledgeRoom)
{{ dd($knowledgeRoom) }}
#endforeach
#endforeach
#endforeach
web.php
Route::view('/', 'Home.master')->name('index');
But I see this demo, it is white page.

get target user permission name according to role

im managing my registerd users... now i want see which user have which permission according the her/his role .. i want to show permissions in check box and make them check if user have that role. problem is target user permission according her role
my controller to view target user permission:
public function view(Request $request, User $user){
$roles = Role::with('permissions')->get();
$permissions = Permission::get();
return view('adminarea.roles.view', compact('roles','user', 'permissions'));
}
Blade file:
#foreach ( $permissions as $per )
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="permissions_ids[]" id="permissions"
value="{{ $per->id }}" style="margin-right:5px" #if (?)
checked="true"
#endif>
<label class="custom-control-label" for="permissions">{{ $per->name }}</label>
</div>
#endforeach
Model Relations :
Role table:
public function users()
{
return $this
->belongsToMany('App\User')
->withTimestamps();
}
public function permissions()
{
return $this->belongsToMany(Permission::class, 'roles_permissions');
}
Permission table:
public function roles()
{
return $this->belongsToMany(Role::class, 'roles_permissions');
}
User table:
public function roles()
{
return $this->belongsToMany(Role::class, 'users_roles');
}
Table Structure :
this is my roles_permission schema:
Schema::create('roles_permissions', function (Blueprint $table) {
$table->unsignedBigInteger('role_id');
$table->unsignedBigInteger('permission_id');
//FOREIGN KEY CONSTRAINTS
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
//SETTING THE PRIMARY KEYS
$table->primary(['role_id', 'permission_id']);
});
and users_role schema :
Schema::create('users_roles', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('role_id');
//FOREIGN KEY CONSTRAINTS
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
//SETTING THE PRIMARY KEYS
$table->primary(['user_id', 'role_id']);
});
permission table :
Schema::create('permissions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
and role table schema:
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
You can make use of laravel policies here.
Create a policy for your Users.
Then create functions like canViewPosts, canAddPosts, canSeeViews, etc. and in each check if the the user has permission to do so.
Example UserPolicy
public function canView(User $user){
return $user->permissions->canView; //given you have permissions relation on user
}
Then in your PostController you go like
$this->authorize('canView', User::class);
Check more in here:
https://laravel.com/docs/5.8/authorization#introduction

show last post from each category

I have two models Post and Category
// migration post
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('body');
$table->string('image');
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('categories');
$table->timestamps();
});
}
// migration category
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
How can I display only the last post from each category in home page?
Hiren was close, but you need to go from the category since your post is owned by the category
$category->posts()->latest()->first();
Alternatively you could work backwards:
$post = Post::latest()->whereHas('category', function($q) use($category_id) {
return $q->where('id', $category_id);
})->first();
For this to work you'll need to define your model relationships:
Category Model needs this function:
public function posts()
{
return $this->hasMany(App\Post::class);
}
Post Model needs this function:
public function category()
{
return $this->belongsTo(App\Category::class);
}
To respond to Alexey Mezenin, we can just pass a callback to with() to define which posts we want to pull in for each category, performing the correct eager load.
Category::with(['posts' => function($q) {
return $q->latest()->first();
})->get();
An Eloquent solution for loading categories with latest post is to create an additional hasOne() relationship in the Category model:
public function latestPost()
{
return $this->hasOne(Post::class)->latest();
}
And then use eager loading:
Category::with('latestPost')->get();
This will generate just 2 queries to DB.
public function up()
{
Schema::create('news', function (Blueprint $table) {
$table->increments('id');
$table->string('slug')->unique();
$table->unsignedInteger('author_id');
$table->unsignedInteger('category_id');
$table->string('subject');
$table->text('short');
$table->text('content');
$table->integer('view')->default(0);
$table->integer('status')->default(0);
$table->string('image');
$table->timestamps();
$table->foreign('author_id')
->references('id')->on('users')
->onDelete('cascade');
// $table->foreign('category_id')
// ->references('id')->on('categories')
// ->onDelete('cascade');
});
// Schema::enableForeignKeyConstraints();
}
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
}
in contoller:
$latestpostlist = News::whereIn('created_at',function($query){
$query->select(DB::raw('max(created_at)'))
->from('news')
->groupBy('category_id');
})->get();
in your case news will be post. this query worked for me

Resources