HasMany Eloquent relation in laravel 5.4 - php

I try to get the number of logged user posts count so it shows to logged user for example how many post or comment they published so far:
What I have so far is author_id column in posts table which will refer to user id
This is my Post model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function author() {
return $this->belongsTo('App\User');
}
}
and this is my User model:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'role_id',
'email',
'password',
'name',
'avatar',
'remember_token',
'created_at',
'updated_at'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function posts()
{
return $this->hasMany('Post', 'author_id');
}
}
This is my PostController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use App\Auth;
use App\User;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$posts = Post::orderBy('created_at', 'desc')->paginate(15);
$countTodayOrders = Post::whereRaw('Date(created_at) = CURDATE()')->count();
return view('theme.index', compact('posts', 'countTodayOrders'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function single($slug) {
$post = Post::where('slug', '=', $slug)->first();
$countTodayOrders = Post::whereRaw('Date(created_at) = CURDATE()')->count();
return view('theme.single', compact('post', 'countTodayOrders'));
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
}
Anyone knows what is my mistake and how to fix it?

Well i figure it out :)
i ignored all model roles and directly used controller inserted data from Database and compare it with user id if it's true (same) will return the number.
here is the code for you if you need it PostController:
public function index()
{
$posts = Post::orderBy('created_at', 'desc')->paginate(15);
$countTodayOrders = Post::whereRaw('Date(created_at) = CURDATE()')->count();
$postscount = DB::table('posts')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('users')
->whereRaw('author_id = id');
})
->get();
return view('theme.index', compact('posts', 'countTodayOrders', 'postscount'));
}

Related

ErrorException Trying to get property 'User' of non-object ( laravel )

I am getting the error:
ErrorException Trying to get property 'User' of non-object
from the statements below which don't seem to work:
$user = Mobile::find(3)->User;
dd($user);
rest of the code is as follows:
usercontroller.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Mobile;
use Hash;
class UserController extends Controller
{
public function addUserMobile()
{
$user = new User;
$user->name = "Test Name";
$user->email = "test#mnp.com";
$user->password = Hash::make("12345678");
$user->save();
$mobile = new Mobile;
$mobile->mobile = '123456789';
$user->mobile()->save($mobile);
}
public function index()
{
// get user and mobile data from User model
$user = User::find(3);
// var_dump($user->name);
// var_dump($user->mobile->mobile);
// // get user data from Mobile model
$user = Mobile::find(3)->User;
dd($user);
// // get mobile number from User model
// $mobile = User::find(3)->mobile;
// dd($mobile);
}
}
mobile.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function mobile()
{
return $this->hasOne(Mobile::class);
// note: we can also inlcude Mobile model like: 'App\Mobile'
}
}
mobile table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMobilesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('mobiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('mobile');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('mobiles');
}
}
mobile database
user database
"3" is user_id btw.
The problem is you are querying the Mobile with id 3 (which does not exist) and then calling the user relation.
$user = Mobile::find(3)->user;
Since Mobile::find with an id that doesn't exist returns null, you are calling ->user on null, and you will get the error you mentioned.
Also, you should add a belongsTo relation in your Mobile model:
public function user()
{
return $this->belongsTo(User::class);
}
Now, after fixing your query to use user_id, you can do:
$user = Mobile::where('user_id', 3)->first()->user;

Laravel policy return unauthorized

I am trying to implement policies in my project. All tries have proven unsuccessful despite following documentation to the letter. And also read numerous posts on SO about it and other media. I did as described in docs, but nonetheless it doesn't work. What gives?
In AuthServiceProvider:
<?php
namespace App\Providers;
use App\User;
use App\Job;
use App\Policies\JobPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
'App\Job' => 'App\Policies\JobPolicy',
//Job::class => JobPolicy::class,
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
In policy:
<?php
namespace App\Policies;
use App\Job;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class JobPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any jobs.
*
* #param \App\User $user
* #return mixed
*/
public function viewAny(User $user,Job $job)
{
//return (($user->isAdmin() || $user->isModerator() || $user->isUser()) && $user->status==1);
//return ($user->isMod());
return true;
}
In controller:
public function index()
{
$this->authorize('viewAny', User::class, Job::class);
return view("jobs.index");
}
My User model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Role;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',"role_id"
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function role(){
return $this->belongsTo("App\Role", "role_id");
}
public function isMod()
{
$user = User::find(auth()->user()->id);
$role = $user->role()->first()->name;
if($role==="job board moderator"){
return true;
}
else{
return false;
}
}
}
And Job model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\User;
class Job extends Model
{
protected $fillable = [
"title", "description", "email"
];
public function user(){
return $this->belongsTo("App\User","user_id");
}
}
In policy:
public function viewAny(User $user)
{
return true;
}
In controller:
public function index()
{
$this->authorize('viewAny', Job::class);
return view("jobs.index");
}
The way to call a model policy method changes depending on the number of parameters it has.
No object
/* In policy*/
public function viewAny(User $user)
/* In controller */
$this->authorize('viewAny', Job::class)`
1 object
/* In policy*/
public function view(User $user, Job $job)
/* In controller */
$this->authorize('view', $job)
More than 1 object
/* In policy*/
public function view(User $user, Job $job, AnotherModel $model)
/* In controller */
$this->authorize('view', [$job, $model])
Source: https://laravel.com/docs/5.8/authorization#creating-policies

I want to select my balance "column" From user table laravel

I'm a beginner in laravel framework,I am in the course of developing an API,and I want to select from users table balance of user when I get her Id in api So I do what I found in documentations in my contoller and i use postman to test my work but always I get a error
this is my controller:
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
class MyBalanceController extends Controller
{
public function index(Request $request)
{
# code...
// $Ads = ads::all();
// return $this->sendResponse($Ads->toArray(), 'Ads read succesfully');
// This is the name of the column you wish to search
$input = $request->all();
$validator = Validator::make($input, [
'user_id'=> 'required'
] );
$Cards = User::where('user_id','=', $request->user_id)->pluck('balance')->toArray();
//$user = Auth::user();
// $Cards = DB::select('select balance from users where id = :id', ['id' => 1]);
return response()->json(['Cards'=>$Cards]);
}
}
this is my modal :
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','username','lastname','tel','adress','balance'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
At first you can go to your .env file and set APP_DEBUG to true so you can see your exceptions when developing your app.
Regarding your problem try
$balance = User::findOrFail($request->user_id)->balance;
return response()->json($balance);
If no user was found with that id then a 404 HTTP error will be thrown

Laravel error Column not found

Error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'products.id' in 'where clause' (SQL: select * from products where products.id = 1 limit 1)
I do have table 'products' with a 'product.id' field. Not sure why I am getting this error. I get this error when I
access /product/{{product_id}}
access /edit
Home Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$user_id = auth()->user()->id;
$user = User::find($user_id);
return view('home')->with('products',$user->products);
}
}
ProductController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\product;
class productController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth',['except' => ['index','show']]);
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$products = product::orderBy('created_at','desc')->paginate(10);
//$products = product::where('type','major')->get();
return view('products.index')->with('products',$products);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('products.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request,[
'title' => 'required',
]);
//create product
$product = new product;
$product->title = $request->input('title');
$product->venue = $request->input('venue');
$product->city = $request->input('city');
$product->country = $request->input('country');
$product->description = $request->input('description');
$product->date = $request->input('date');
$product->user_id = auth()->user()->id;
$product->save();
return redirect('/products')->with('success','product Created');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$product = product::find($id);
return view('products.show');
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
$product = product::find($id);
return view('products.edit')->with('product',$product);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'title' => 'required'
]);
$product = product::find($id);
$product->title = $request->input('title');
$product->save();
return redirect('/products')->with('success','product updated');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$product = product::find($id);
$product->delete();
return redirect('/products')->with('success','product deleted');
}
}
Show.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<h1 class="centre">{{$product->title}}</h1>
<div class="well-xs">
#if(!Auth::guest())
#if(Auth::user()->id == $product->user_id)
Edit
{!!Form::open(['action' => ['productcontroller#destroy', $product->product_id], 'method' => 'POST'])!!}
{{Form::hidden('_method', 'DELETE')}}
{{Form::submit('Delete', ['class' => 'btn btn-danger'])}}
{!!Form::close()!!}
#endif
#endif
</div>
<div>
<div>
<h4>product Date: {{$product->date}}</h4>
<h4>product Venue: {{$product->venue}}</h4>
<h4>product Location:{{$product->city}}</h4>
<h4>product Description: </h4>
<p>{{$product->description}} </p>
</div>
</div>
<hr>
Written on
</hr>
</div>
#endsection
Products table schema: I added user_id manually in sql. migrate wasnt working when I tried making a separate migration to add_user_id_to_table
{
Schema::create('products', function (Blueprint $table) {
$table->increments('product_id');
$table->string('title',200);
$table->string('venue',200);
$table->text('city',200);
$table->text('country',200);
$table->string('description');
$table->date('date',200);
$table->timestamps();
});
}
user.php model:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function products(){
return $this->hasMany('App\Product');
}
}
Product.php model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
//Table NAME
protected $table = 'products';
//PRIMARY KEY
public $primaryKey = 'id';
//Timestamps
public $timestamps =true;
public function user(){
return $this->belongsTo('App\User');
}
}
When you modify your migrations, you still need to update the database. So you should try
php artisan migrate:fresh
That will erase your database and migrate it again
Also, you don't need to query for the current user in your controller
Instead of this:
public function index()
{
$user_id = auth()->user()->id;
$user = User::find($user_id);
return view('home')->with('products',$user->products);
}
You can simply use:
public function index()
{
return view('home')->with('products', auth()->user()->products);
}
EDIT:
Your products migration doesn't have a column called id defined but product_id instead.
Also, you're declaring a belongsTo relation in product to user while you don't have the id of the user on that table.
A relation belongsTo means that you have the id of the related model. For example
class User extends Model
{
public function posts()
{
return $this->hasMany(App\Post::class);
}
}
class Post extends Model
{
public function user()
{
return $this-belongsTo(App\User::class);
}
}
This is possible because posts table has a field called user_id. Because a Post belongs to a user.
You don't need this code:
//Table NAME
protected $table = 'products';
//PRIMARY KEY
public $primaryKey = 'id';
//Timestamps
public $timestamps =true;
Laravel handle all of that automatically, you're defining the default values
Change in your User model
public function products(){
return $this->hasMany("App\Product","product_id","product_id");
//return $this->hasMany("App\Product","foreign_key","local_key");
}

Laravel 5 - Laracast Easy Auth - Saving an article

I was following a tutorial on laracast about easy auth (Easy Auth), but there were some gaps on the video, i had to declare
use Auth;
to be able to get the current user, however, when i save the article i get this error
FatalErrorException in ArticleController.php line 42:
Call to undefined method Illuminate\Database\Eloquent\Collection::save()
where the corresponding code in my ArticleController is
public function store(ArticleRequest $request)
{
$article = new Article($request->all());
Auth::user()->articles->save($article);
return redirect('blog');
}
My Article model:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
class Article extends Model {
protected $fillable = [
'title',
'body',
'published_at',
'user_id'
];
protected $dates = ['published_at'];
public function scopePublished ($query)
{
$query->where('published_at', '<=', Carbon::now());
}
public function scopeUnpublished ($query)
{
$query->where('published_at', '>', Carbon::now());
}
public function setPublishedAtAttribute($date)
{
$this->attributes['published_at'] = Carbon::parse($date);
}
public function user()
{
return $this-> belongsTo('App\User');
}
}
My User model
<?php namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name', 'email', 'password'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
public function articles()
{
return $this-> hasMany('App\Article');
}
}
try with this
Auth::user()->articles()->save($article);
store action
public function store(ArticleRequest $request)
{
$article = new Article($request->all());
Auth::user()->articles()->save($article);
return redirect('blog');
}

Categories