Call to a member function details() on null? - laravel

My code is:
$user = User::create([
'email' => $request->email,
'password' => Hash::make($request->password),
]);
$user_details = [
'name' => $request->name,
'address' => $request->address,
'lastname' => $request->lastname,
'secondname' => $request->secondname,
'inn' => $request->inn,
'fincode' => $request->fincode,
];
$user->details()->create($user_details);
Model User is:
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
public function details()
{
return $this->hasOne(UserDetails::class, 'user_id', 'id');
}
}
UserDetails model is:
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserDetails extends Model
{
protected $table = 'enterprise';
protected $fillable = ['name', 'lastname', 'secondname', 'address', 'inn', 'fincode'];
}

I believe that your $user has not been persisted, hence having the error, in your case $user is null, that's why you cannot call details on null object. Make sure that you use all the required fields on your user.
You might be missing the fillable array in the User model if the one that you shared is the full content, then add this:
protected $fillable = [ 'email', 'password'];

Related

How to seed 2 tables that are related to each other in Laravel 8

So I have 2 tables one is the User table and the other is the related UserProfile table. I wanted to fill them with dummy data but I cant get it to work that when I run the seeder it will fill both tables. For now it will fill the User table with dummy data only.
Solution found(any sugestions are welcome)
User.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;
use Laravel\Sanctum\HasApiTokens;
use App\Models\UserProfile;
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable, HasApiTokens;
protected $table = 'user';
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
public function profile()
{
return $this->hasOne(UserProfile::class, 'user_id');
}
}
UserProfile.php
namespace App\Models;
use App\Models\User;
class UserProfile
{
protected $table = 'user_profile';
protected $fillable = [
'user_id',
'firstname',
'lastname',
];
public function user()
{
return $this->belongsTo(User::class, 'id');
}
}
UserFactory.php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => $this->faker->firstName,
'email' => $this->faker->unique()->safeEmail,
'active' => mt_rand(0,1),
'role' => mt_rand(0,5),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'remember_token' => Str::random(10),
];
}
}
UserProfileFactory.php
namespace Database\Factories;
use App\Models\UserProfile;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserProfileFactory extends Factory
{
protected $model = UserProfile::class;
public function definition()
{
return [
'user_id' => User::Factory(),
'firstname' => $this->faker->firstName,
'lastname' => $this->faker->lastName,
'default_language' => 'en',
];
}
}
DatabaseSeeder.php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
//solution
User::factory(100)->hasProfile(1, function (array $attributes, User $user) {
return ['firstname' => $user->name];
})->create();
}
}
Could you give this a try:
public function definition()
{
$user = [
'name' => $this->faker->firstName,
'email' => $this->faker->unique()->safeEmail,
'active' => mt_rand(0, 1),
'role' => mt_rand(0, 5),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'remember_token' => Str::random(10),
];
UserProfile::create([
'user_id' => $user->id
//any other extra data you have in the user_profiles table
]);
return $user;
}
You need to use for method, Belongs To Relationships
UserProfile::factory()
->for(User::factory()->state([
'name' => 'name', // optional
...
]), 'profile')->state([
'firstname' => 'firstname', // optional
...
])->create();
or
$users = User::factory()->count(100)->create();
foreach ($users as $key => $user) {
UserProfile::factory()
->for($user, 'profile')
->create();
}

Laravel Authentication Why im getting data from other model or database table but in model itself it cannot?

The problem is, when I try to login using suitspecialist login it wont login using credentials from suitspecialist database table. however, it will login when I use credentials from blogger database table in suitspecialist login form.
really weird
Note:blogger login works fine just the suitspecialist login and I can register and store data to suitspecialist databe table ..
This is my blogger model
class Blogger extends Authenticatable
{
use Notifiable;
protected $guard = 'blogger';
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
}
Suitspecialist model
class Suitspecialist extends Authenticatable
{
use Notifiable;
protected $guard = 'suitspecialist';
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
}
Login controller of blogger
public function showBloggerLoginForm()
{
return view('auth.login', ['url' => 'blogger']);
}
public function bloggerLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if (Auth::guard('blogger')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {
return redirect()->intended('/blogger');
}
return back()->withInput($request->only('email', 'remember'));
}
Login controller of suitspecialist
public function showSuitspecialistLoginForm()
{
return view('auth.login', ['url' => 'suitspecialist']);
}
public function suitspecialistLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if (Auth::guard('suitspecialist')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {
return redirect()->intended('/suitspecialist');
}
return back()->withInput($request->only('email', 'remember'));
}
Check your 'model' attribute in config/auth.php. I think it is set to 'blogger'. Change it to the model you to use for authentication.

Auto Login After successful registration in laravel 6 getting an error

I am getting an error while trying to Auto Login After successful registration in laravel 6 getting the following error.
Argument 1 passed to Illuminate\Auth\SessionGuard::login() must implement interface Illuminate\Contracts\Auth\Authenticatable, null given, called in
My Registercontroller is
class RegisterController extends Controller
{
use RegistersUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function __construct()
{
$this->middleware('guest');
// $this->middleware(['auth','verified']);
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'min:3'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
$username = slugify($data['name'])."-".mt_rand(10000, 99999);
$user = User::create([
'name' => $data['name'],
'username' => $username,
'email' => $data['email'],
'password' => Hash::make($data['password']),
'email_token' => base64_encode($data['email']),
]);
Auth::loginUsingId($user->id);
}
}
User Model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Jobs\SendEmailJob;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'email','name','password','username','picture',
'ip_address','email_verified_at','email_token','verified'
];
/**
* 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',
];
function socialProviders(){
return $this->hasMany(socialProvider::class);
}
// This is the code define in the sendEmailVerificationNotification
public function sendEmailVerificationNotification()
{
SendEmailJob::dispatch($this);
}
}
You have overwritten the registration logic, but you have ignored the fact that create method needs to return an instance of App\User - or at least a class that implements Authenticatable.
Take a look at the original logic; you will see that the docblock shows that an instance of App\User is being returned and that the original implementation returns the result of the User::create() call.
To get your custom method working, update it like so:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'username' => slugify($data['name'])."-".mt_rand(10000, 99999);,
'email' => $data['email'],
'password' => Hash::make($data['password']),
'email_token' => base64_encode($data['email']),
]);
}
Laravel will take care of logging the user in by default anyway.

Laravel 5 - SoftDelete not working

I've been searching a lot in the web and StackOverflow itself, however I can't find a solution to the problem.
Soft deleting simply refuses to work. The database has the deleted_at field. User model has everything needed to supposedly work, however data is still hard deleted when I call the Delete() method. I don't know what I'm doing wrong.
Laravel Version: 5.3.31
destroy method
public function destroy($id)
{
//$this->authorize('delete', User::class);
$user = User::find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
$user->Delete();
Flash::success('User deleted successfully.');
return redirect(route('users.index'));
}
user model
namespace App\Models;
use Eloquent as Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
use SoftDeletes;
public $table = 'users';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
protected $dates = ['deleted_at'];
public $fillable = [
'name',
'email',
'password',
'role',
'remember_token'
];
protected $casts = [
'id' => 'integer',
'name' => 'string',
'email' => 'string',
'password' => 'string',
'role' => 'string',
'remember_token' => 'string'
];
public static $rules = [
'name' => 'required|max:255',
];
}
I appreciate anything that can help me to solve this.
Thanks in advance.

Request Data to Model Function

I'm trying to find out why when I dd($request->all()) in the store method of my controller everything is correct, however when I send it to the model function register() its no where to be seen.
I'm not quite sure what I'm doing wrong.
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class UsersController extends Controller
{
public function store(Request $request, User $user)
{
$this->authorize('delete', $user);
$this->validate($request, [
'firstName' => 'required|min:3',
'lastName' => 'required|min:3',
'displayName' => 'required|min:3',
'emailAddress' => 'required|email|unique:users,email',
'password' => 'required|min:3',
'role' => 'required|exists:roles,id'
]);
$userRegistered = $user->register(
new User($request->all())
);
if ($userRegistered) {
flash()->success('Success', 'The user has been successfully created!');
} else {
flash()->error('Error', 'The user could not be successfully created!');
}
return redirect()->to(route('users'));
}
}
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable
{
use SoftDeletes;
/**
* Fillable fields for a user.
*
* #var array
*/
protected $fillable = [
'first_name',
'last_name',
'display_name',
'email',
'password',
'role_id'
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function register(User $user)
{
return $user->create([
'first_name' => $user->firstName,
'last_name' => $user->lastName,
'display_name' => $user->displayName,
'email' => $user->emailAdress,
'password' => $user->password,
'role_id' => $user->role
]);
}
}
You've mixed up the formatting of your variables between your request data and your User model.
According to your validation logic, the request data is coming is as camelCase. Yet, according to your $fillable array, the fields on your User model are snake_case. But, even then, in your register method, you're attempting to access the fields on the User model using camelCase.
You haven't given enough information for a definitive answer, but you need to fix the formatting of your variables. For example, change your request fields names from camelCase to snake_case, and make sure you access your fields on the model using snake_case.
You have to pass a list of attributes to "validate" method.
//...
$this->validate($request->all(), [
'firstName' => 'required|min:3',
'lastName' => 'required|min:3',
'displayName' => 'required|min:3',
'emailAddress' => 'required|email|unique:users,email',
'password' => 'required|min:3',
'role' => 'required|exists:roles,id'
]);
One more thing..check if you are using "web" middleware. (Kernel.php => MiddlewareGroups). Add that middleware to your route.

Resources