Reputation: 4319
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
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
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