Peter Wilson
Peter Wilson

Reputation: 4319

Laravel 5.3 ErrorException in Model.php line 2709

I am using Laravel 5.3 and I want to send verification mail using the following

php artisen make:auth
php artisen make:mail ConfirmationEmail

ConfirmationEmail.php

<?php

namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class ConfirmationEmail extends Mailable
{
use Queueable, SerializesModels;

/**
 * Create a new message instance.
 *
 * @return void
 */
public $user;
public function __construct(User $user)
{
    $this->user = $user;
}

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.confirmation');
}
}

emails/confirmation.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sign Up Confirmation</title>
</head>
<body>
  <h1>Thanks for signing up!</h1>

  <p>
    We just need you to <a href='{{ url("register/confirm/{$user->token}") }}'>confirm your email address</a> real quick!
</p>
</body>
</html>

UserController.php

public function register(Request $request)
{
    $validator = Validator::make($request->all(), [
        'email'         => 'required|email|unique:users',
        'name'          => 'required|string',
        'password'      => 'required|string|min:6',
        'country'       => 'required'
    ]);
    if ($validator->fails()) {
        return response()->json(['error'=>$validator->errors()], 401);
    }
    $input = $request->all();
    $input['password'] = bcrypt($input['password']);
    $input['user_pin'] = $this->generatePIN();
    $user = User::create($input);
    Mail::to($user->email)->send(new ConfirmationEmail($user));
    $success['token'] =  $user->createToken('MyApp')->accessToken;
    $success['user']  =  $user ;
    $now      = Carbon::now();
    UserLocation::create(['user_pin' => $input['user_pin'] , 'lat'=> 0.0 , 'lng' => 0.0 , 'located_at' => $now]);
    return response()->json(['success'=>$success], $this->successStatus);
}

Models/User.php

<?php

vnamespace App\Models;
use App\User as BaseUser;

class User extends BaseUser
 {

  /**
  * The attributes that should be hidden for arrays.
  *
  * @var array
  */
  protected $hidden = [
    'password', 'remember_token',
  ];


  public function groups(){
    return $this->belongsToMany(Group::class, 'group_member', 'member_id', 'group_id');
  }

public function sentRequests(){
    return $this->hasMany(Request::class, 'from_user_pin', 'user_pin');
  }

public function receivedRequests(){
    return $this->hasMany(Request::class, 'to_user_pin', 'user_pin');
  }

public function locations(){
    return $this->hasMany(UserLocation::class, 'user_pin', 'user_pin');
  }
}

App\User.php

<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;


class User extends Authenticatable
{
 use HasApiTokens, Notifiable;


protected $guarded = ['id'];

/**
 * 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',
 ];

}

I am now getting this error

ErrorException in Model.php line 2709: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation (View: /var/www/html/group_map_v1/resources/views/emails/confirmation.blade.php)

Upvotes: 0

Views: 395

Answers (2)

Alexey Mezenin
Alexey Mezenin

Reputation: 163758

You're getting this error, you're trying to use a model method as a relationship, but this method doesn't return one. The relationship should look like this:

public function relationship()
{
    return $this->hasMany(Model::class);
}

Update

HasApiTokens trait has a method named token() which is a simple accessor:

public function token()
{
    return $this->accessToken;
}

When you do $user->token, Laravel sees this method and trying to use it as a relationship.

So, what you want to do is to rename your token property in the users table to something else.

Thanks to @lagbox for the pointing in the right direction.

Upvotes: 1

lagbox
lagbox

Reputation: 50491

token is a method on the model. When you try to access the dynamic property on the model, it looks for an attribute then for relationship method (or already loaded relationship) by that name.

You have no attribute named token. When you try to access it via the dynamic property it looks for a method named token (this is how it can access relationships via that property). When it does this it hits that method and that method does not return a relationship type object. So Eloquent breaks at that point as that property is for attributes and relationships, and it can't do anything with it.

asklagbox - blog - eloquent misunderstandings - dynamic properties and relationships

Upvotes: 2

Related Questions