Create an entity with foreign Key - php

I'm currently learning Laravel and I would like to create a new Entity with a foreign key in it (basically, a User who's linked to an Address), so far I'm doing this:
$newAddress = App\Address::create([]);
return App\User::create([
'username' => $data['username'],
'mail' => $data['mail'],
'password' => bcrypt($data['password']),
'address_id' => $newAddress->getAttributes()['id']
]);
But I'm pretty sure there is a better solution, I just can't figure out how. I'm using the default AuthController generated by the Artisan console.

If you have your relations setup, you can use those to associate the address to the user.
$address = App\Address::create();
$user = new App\User([
'username' => $data['username'],
'mail' => $data['mail'],
'password' => bcrypt($data['password']),
]);
$user->address()->associate($address);
$user->save();

Related

Laravel 8.x - Storing data with Eloquent Relationship

I've got a User model that hasOne Membership model, with a users table and a memberships table (each entry in the memberships table has a foreign key linked to a user_id).
I've made a registration page that lets the user have a 7 days trial period on the membership but I'm having trouble storing the data.
This is the dd() of the data in the registration form:
"_token" => "ckRlMligEyTwu7ssOi4TmesycbsPpVQlrJ4jQaBd"
"username" => "JaneDoe"
"password" => "password"
"password_confirmation" => "password"
"expiration" => "2021-04-30"
Now in my controller I've got the following store() method:
public function store(Request $request) {
// validating
$this->validate($request, [
'username' => ['required', 'max:200'],
'password' => 'required|confirmed',
'expiration' => 'required'
]);
// storing
User::create([
'username' => $request->username,
'password' => Hash::make($request->password),
'expiration' => $request->expiration
]);
}
This won't store anything in the memberships table and I have no idea how to correctly write the store method using the Model's Eloquent Relationships declared.
Thanks for the help.
EDIT:
While trying to make some sense i've modified the store() function, now looks like this:
public function store(Request $request) {
// validating
$this->validate($request, [
'username' => ['required', 'max:200'],
'password' => 'required|confirmed',
'expiration' => 'required'
]);
// storing
User::create([
'username' => $request->username,
'password' => Hash::make($request->password)
])->membership(Membership::create([
'expiration' => $request->expiration
]));
}
Now seems like Laravel doesn't know where to get the user_id of the newly created user, like the error suggests:
SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into `memberships` (`expiration`, `updated_at`, `created_at`)
Your solution is to do:
User::create([
'username' => $request->username,
'password' => Hash::make($request->password)
])->membership()->create([
'expiration' => $request->expiration
]);
Using the relation (membership() not membership as an attribute) will already know the relation key (user_id in this case).
You can see more info about this in the documentation.
Other way of doing same is:
$membership = new Membership([
'expiration' => $request->expiration
]);
User::create([
'username' => $request->username,
'password' => Hash::make($request->password)
])->membership()->save($membership);
More info about save() on the documentation.

Laravel Auth Check For An Organization

when a user tries to register I require them to enter an organization ID, I want that organization ID to be checked against my Organization table and see if it exists. If it exists then register the user and if it fails then return an error message. I've been looking around online and couldn't personally find anything like this. If anybody could help, I'd greatly appreciate it.
I am using Laravel 5.6 with the default auth.
Validator:
return Validator::make($data, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'org_id' => 'required|string|max:16',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
User Create:
return User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'org_id' => $data['org_id'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'is_active' => 1
]);
You're looking for the exists rule of Laravel's Validation:
'org_id' => 'required|string|max:16|exists:organizations,id',
The rule is essentially
exists:{table},{column?}
Where table is required, and column is optional, generally used if the name (in this case org_id) is different from the column you want to compare.
For full details, check the Documentation.

Laravel testing is it possible to have followingRedirects after the assertSessionHas

I am testing in laravel and saw yesterday that you can't have followingRedirects before assertSessionHas. So I wanted to know if it is possible to have it after the assertSessionHas without repeating the whole test code. I have now this a temporary solution:
$response = $this->post('/signup', [
'username' => 'Testing',
'email' => 'testing#test.com',
'password' => 'secret',
'password_confirmation' => 'secret',
]);
$this->assertDatabaseHas('users', ['username' => 'Testing', 'email' => 'testing#test.com']);
$response->assertSessionHas('success', 'Your account has been created!');
$code = $this->followRedirects($response)->getStatusCode();
$this->assertEquals(200, $code);
But I want to know if you are able to change the response later on with the followingRedirects instead of using it this way.
When sending a post request in Laravel using PHPUnit, you don't need to pass the csrf_token(), it is included automatically.
I would refactor your code like this:
$this->post('/signup', [
'username' => 'Testing',
'email' => 'testing#test.com',
'password' => 'secret',
'password_confirmation' => 'secret',
])->assertStatus(200)
->assertSessionHas('success', 'Your account has been created!');
$user = User::latest()->first();
$this->assertEquals('Testing', $user->name);
$this->assertEquals('testing#test.com', $user->email);

How to make auto login after registration in laravel

I have encounterd a problem while regiserting user in laravel, $user suppose to be array which contains all array element while auto login the following code results false. The password save in the database is hash::make('password').
$user_id = $this->user_model->addUser($user);
$post = array('password' => $pass_for_auth, 'email' => $email);
var_dump(Auth::attempt($post,true));die;
Can any one tell me what is the correct problem
You can try to login the user through his $user_id. So your code will be:
$user_id = $this->user_model->addUser($user);
$post = array('password' => $pass_for_auth, 'email' => $email);
Auth::loginUsingId($user_id);
You created the user so it returns an user_id, with the user_id you can login the user.
Hope this works!
More information at: https://laravel.com/docs/5.2/authentication#other-authentication-methods
This would be the standard way to do user registration - you create a new user model instance and pass it to Auth::login() :
// do not forget validation!
$this->validate($request, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
$data = $request->all();
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
Auth::login($user);

Create record with Relation Laravel 5.1

Hi i have the next code for create my records
Institution::create($request->all());
User::create([
'name' => $request['name'],
'lastname' => $request['lastname'],
'phone' => $request['phone'],
'email' => $request['email'],
'password' => $request['password'],
'state' => 1,
'profile_id' => 1,
'institution_id' => Institution::max('id'),
]);
The last attributes for the User thats correct implement so?
The last 3 user attributes , it is correct to do it that way? or is there a better
Using Institution::max('id') creates a race condition. Since the create() static method of Eloquent::Model returns the newly-created model, you can just do:
$institution = Institution::create($request->all());
User::create([
'name' => $request['name'],
'lastname' => $request['lastname'],
'phone' => $request['phone'],
'email' => $request['email'],
'password' => $request['password'],
'state_id' => 1,
'profile_id' => 1,
'institution_id' => $institution->id,
]);
Creating a record with known parent ids is generally fine if your goal is to minimize the number of database queries and you have the ids of the related models.
Another way to do it, though it triggers more update queries, is to use Eloquent's built-in methods for adding related models. For example:
$institution = Institution::create($request->all());
$state = State::find(1);
$profile = Profile::find(1);
$user = new User([
'name' => $request['name'],
'lastname' => $request['lastname'],
'phone' => $request['phone'],
'email' => $request['email'],
'password' => $request['password']
]);
$user->state()->associate($state);
$user->profile()->associate($profile);
$user->profile()->associate($institution);
$user->save();
However, in this situation, since the related models are not already loaded, and you know their ids, there is no need to fetch them only to associate them with the User.

Categories