laravel MyModelClass not found in 1:1 relationship - php

I have a User and a Profile class in my application with 1:1 relationship.
Inside my ProfileController#show I can instantiate and build query perfectly fine for each of them but these two lines :
$userProfile=$profile->with('user')->where('id',1)->firstOrFail();
$userProfile=$user->with('profile')->where('id',3)->firstOrFail();
The first one sends a fatal error Exception with the message: "Class User Not Found" and the message for the second one is "Class Profile Not Found"
I also tried facades and different way of building query but it didn't work.
According to this question I think there is something wrong with my relationship. I passes the foreign_key explicitly, but it doesn't work.
Here is some details:
User class:
class User extends \Eloquent implements UserInterface, RemindableInterface
{
public function profile()
{
return $this->hasOne('Profile', 'id');
}
}
Profile class
class Profile extends \Eloquent
{
public function user()
{
return $this->belongsTo('User', 'id');
}
}
Database schema:
table "users"
id
password
email
username
table "profiles"
id
user_id
about
Thanks in advanced.

If your Model has a namespace you need to insert the full namespaced class as a parameter. Otherwise Eloquent does not know where to find the class.
OR you need to add the models to your classmap in app/config/app.php
class User extends \Eloquent implements UserInterface, RemindableInterface
{
public function profile()
{
return $this->hasOne('\Path\TO\Model\Profile', 'id');
}
}

What about this?
class User extends \Eloquent implements UserInterface, RemindableInterface
{
public function profile()
{
return $this->hasOne('Profile', 'user_id');
}
}
Shouldn't it be a foreign key? http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Relations/HasOne.html

Related

Eloquent get value Many to Many Relationship

This is my Vote model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vote extends Model
{
public function user(){
return $this->belongsTo('App\User');
}
public function options(){
return $this->hasMany('App\Option');
}
}
this is my Option model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Option extends Model
{
public function vote(){
return $this->belongsTo('App\Vote');
}
public function users(){
return $this->belongsToMany('App\User');
}
}
The case is i want to get the users data from many to many relationship in Option model, but started from Vote model. So i get the options data in the Vote model first, then i get the users data in Option model (many to many)
Laravel has no native support for a direct relationship.
I've created a package for cases like this: https://github.com/staudenmeir/eloquent-has-many-deep
class Vote extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function users()
{
return $this->hasManyDeep(User::class, [Option::class, 'option_user']);
}
}

Get the morphMany relationship to a model from the user

Let say i have the following;
User Model;
class User extends Authenticatable
{
public function posts()
{
return $this->hasMany('App\Models\Socials\Post');
}
}
Post Model;
class Post extends Model
{
public function comments()
{
return $this->morphMany('App\Models\Socials\Comment', 'commentable');
}
Comment model;
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
When i used $user = User::find($id); and $user->posts(), it returns all the post of the user, but if i used this method $user->posts()->comments() It return this message Method Illuminate\Database\Query\Builder::comments does not exist.
The question is how can i get all the comments of the user on the said post?
Change:
$user->posts()->comments();
to:
$user->posts->pluck('comments')->collapse();
The method itself returns an instance of Eloquent's query builder allowing you to add to or edit the query if you want. However, if you don't want to edit the query you can access the relationships as properties and Laravel will handle to execution of the query.
Essentially, $user->posts is actually turning into $user->posts()->get() in the background.
Credit to #JonasStaudenmeir.

Load extra table/data into user object

In Laravel 5.6 I'm trying to load data into the user object, so I can view user credentials/settings etc.
Whats annoying is I had it working, but for some reason now It seems to have stopped, and I'm not sure what I've changed to break it.
Anyway I want to load two tables, access and settings. Both of them have user_id field in there with the corresponding user_id in.
In my User.php class I have two functions:
public function access() {
return $this->hasMany(Access::class);
}
public function settings() {
return $this->hasOne(Settings::class);
}
I am not Use-ing them at the top of the class (i.e. use \App\Access) if that makes any difference.
And then the Access class looks like:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Access extends Model
{
protected $table = "access";
}
And the Settings class is very much the same:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Settings extends Model
{
protected $table = "settings";
}
However whenever I try and access Auth::user()->settings or Auth::user()->access I get undefined index: error. It's frustrating because like I said I had it working the other day and I'm not sure what's changed.
Few things you could try here. First, Lazy Eager Load the relationships by loadMissing:
// settings
Auth::user()->loadMissing('settings');
// access
Auth::user()->loadMissing('access');
To load a relationship only when it has not already been loaded, use the loadMissing method
Second, you can use with when querying for a user, although it's not as relevant with using the auth facade:
User::with(['settings', 'access'])->where('atribute', $value)->get();
Last, if you always want the settings and access relationships to always be returned with each user model, set the with attribute on the user model:
public class User {
protected $with = ['settings', 'access'];
...
}
I usually define the inverse relationships on models as well, so Access and Settings would have a BelongsTo relationship defined:
class Access extends Model
{
protected $table = "access";
public function user() {
return $this->belongsTo(User::class);
}
}
class Settings extends Model
{
protected $table = "settings";
public function user() {
return $this->belongsTo(User::class);
}
}

Class 'phone ' not found while implementing eloquent relationship

This is the first time i am trying to use eloquent relationship.I have a userModel and a phoneModel class.They represents users and phone table respectively. Here i am trying to access The phone number of a user when he/she logged in.
users table has the field (id,name,password) and phone table has the
(field id,phone_no,user_id)
phone migration is below:
public function up()
{
//
Schema::create('phone',function(Blueprint $table){
$table->increments('id');
$table->string('phone_no',20);
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
i applied hasOne and belongs to relationship on both models:
userModel.php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
class userModel extends Model implements Authenticatable
{
//
use \Illuminate\Auth\Authenticatable;
protected $table = 'users';
public function phone(){
$this->hasOne('App\Models\phone');
}
}
phoneModel.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class phoneModel extends Model
{
//
protected $table='phone';
public function user()
{
return $this->belongsTo('users');
}
}
Now when i tried to get a phone number from logged user i get an error called class 'phone' not found
Here is the code inside show method of userController:
public function show($user)
{
//
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if($info){
$phone = userModel::find($info->id)->phone;
$data=array('info'=>$info,'phone'=>$phone);
return View::make('user.show')->with($data);
}else{
$info=userModel::where($indicator,'=', Auth::user()->name)->get()->first();
return View::make('user.show')->with('user',$info);
}
}
You named your phone class phoneModel but you added the relationship as $this->hasOne('App\Models\phone');. You also created those classes in the App namespace but referenced them as App\Models\class.
The standard practice is to name your model classes after the model and using uppercase letters. So your classes would be called User and Phone rather than userModel and phoneModel. And the database tables would be users and phones. If you use these standards, Laravel will take care of a lot of things automatically behind the scenes.
User class
namespace App;
class User extends Model implements Authenticatable
{
//
use \Illuminate\Auth\Authenticatable;
//Laravel will assume the User model is in the table `users` so you don't need to specify
public function phone(){
$this->hasOne('App\Phone');
}
Phone Class
namespace App;
class Phone extends Model
{
//Laravel will assume the Phone model is in the table `phones` so you don't need to specify
public function user()
{
return $this->belongsTo('App\User');
}

Laravel 5 check role giving error "trying to get property of non object"

I am very new to Laravel and am trying to implement roles to users.
I have created the Role table and Model associated with it
I have added a column role to the users table.
I am now trying to check that role in the User model
EDIT: After an answer/explanation here I changed role to role_id in the users table but I am still getting the same error.
Here is 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;
use Auth;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
// more stuff
public function role()
{
return $this->belongsTo('App\Role');
}
public function isAdmin()
{
return $this->role->slug == 'admin';
}
}
And my Role Model
<?php namespace App;
use Illuminate\Database\Eloquent\Model as Eloquent;
class Role extends Eloquent {
protected $table = 'roles';
public function users()
{
return $this->hasMany('App\User');
}
}
When I go to my admin page I have the following function...
public function index(User $user)
{
if ($user->isAdmin()) {
return view('admin/home_admin');
}
else {
return redirect('home');
}
}
However Im getting the error...
Trying to get property of non-object in User.php line 62 at
HandleExceptions->handleError('8', 'Trying to get property of
non-object', '/home/vagrant/Code/esearch/app/User.php', '62', array())
in User.php line 62
I have tried this while logged in and not logged in with the correct role. Am I missing something obvious here?
The problem with the code started off with the role_id setting that #user3158900 noticed. This was something that needed to be resolved.
But you were using the improper form of user when attempting to see what is happening. Instead of the User $user you need Guard $user or Guard $auth as it is more commonly seen. You can also use Auth::user()->isAdmin().
There is one last thing that should be looked at that I did not mention in my comment above.
If the user is not logged in and is a guest you will get an error trying to find Auth::user() and it will fail. This is because Auth::user() is null when you are a guest. So you should do a check that is logged in.
You can either use !Auth::guest() or Auth:check() (which is cleaner).
Hopefully this is all good for you!
You are close. Laravel assumes the foreign key for role to be role_id but since you are using role, you need to set that up in your relation as well.
In your Role model.
public function users()
{
return $this->hasMany('App\User', 'role');
}
In your User model.
public function role()
{
return $this->belongsTo('App\Role', 'role');
}
Because role would both be a relating function and a column in your table, it would be best to modify the column name to role_id to match what Laravel expects.

Categories