Add the inserted id to the pivot table - laravel

I have a users, items, user_item tables. I need to populate the user_item table with a user_id and item_id when a user is created.
so far, I have a basic registration function
public function register(Request $request) {
$user = User::create([
'name' => $request->name,
'user_type' => $request->user_type,
'email' => $request->email,
'password' => bcrypt($request->password)
]);
$token = auth()->login($user);
return $this->respondWithToken($token);
}
So far it saves only to the users table ofcourse.
I've looked at some documentations on using attach(), however, I got stuck on this one..
In the register function, i added a $item array:
$item = Item::create([
'user_id' => !!!!, -> How do I get the id of the inserted user
'instrument_id' => $request->instrument_id
]);
$user->role()->attach($item)
Also, what is role()? is it a built-in laravel function?
Note that I haven't tried running this function since I got stuck on these problems. So I don't event know if it's gonna work.
Anyone help me on this one? I'm a laravel newbie and got really confused on the documentations.

the method create return the model it self after loading it's attributes from db,
so when you want the user id just use $user->id after create() method.
for the default permission that shipped with laravel it is
spatie/laravel-permission
and to assign role to a user you can use:
$user->assignRole('writer'); // just set role name

Related

Laravel create command wont insert a value in database

Hello i am new to Laravel so currently im doing a CRUD. I have created this insert function that works well except one value is never inserted. This is the code below:
public function storeClient(Request $request) {
$request->validate([
'name' => 'required',
'email' => 'required|email',
'phone' => 'nullable',
'age'=>'required',
]);
Client::create($request->all());
dd($request->phone);
return redirect('/')->with('msg', 'Client Saved successfully!.');
}
the phone' => 'nullable', value will not insert in the database unless i update the existing values. I tried this command dd($request->phone); and it shows the correct value from the user input. Any idea why the value will be inserted as null on database?
This is the value output when i make the dd command
I tried this other code which works well but im trying to use the default create() function of laravel. This is the other code i did that works well:
public function storeClient()
{
$client = new Client();
$client->name = request('name');
$client->email = request('email');
$client->phone_number = request('phone');
$client->age = request('age');
$client->save();
return redirect('/')->with('msg','Client Saved successfully!');
}
first i did not like nullable here 'phone' => 'nullable',
then u should see what do you register in your Client table phone_number or phone,
$client->phone_number = request('phone');
i think you should rename your input name phone to phone_number and will work
When you are trying to use default create method the fields names must be same as in database.
$client->phone_number = request('phone');
this line works due to the name you entered manually.
to work with default create method change the name of field in database as phone.

How to create an invitation system in Laravel PHP

Im new in laravel and I'm watching a youtube playlist to build my 1st project....
now I'm trying to implement an inv only system
so the register form looks like
username:
inv code:
password:
I've already created a migration which has
user_id - this is user id of the user who created the invite
code - the code which will get validated at time of registration and then deleted
{timestamps}
so the issue im having is:
how do I verify that the invite entered by user exists in the table "inv_codes" and matches the column "code" and then delete it after registration is complete
here is a minimal reproducible example
lass RegisterController extends Controller
{
public function __construct()
{
$this->middleware(['guest']);
}
public function index()
{
return view('auth.register');
}
public function submit(Request $request)
{
$this->validate($request, [
'username' => 'required|max:6',
'password' => 'required',
]);
User::create([
'username' => $request->username,
'password' => Hash::make($request->password),
]);
auth()->attempt($request->only('username', 'password'));
return redirect()->route('dashboard');
}
}
Suppose that you have code column in both users and inv_codes tables. Now during registration, you can use validation. Something like this:
$request->validate([
'code' => 'required|exists:inv_codes,code',
// ... rest of registration fields
]);
Then you can delete that row in inv_codes table by something like this:
You can read more at: https://laravel.com/docs/8.x/validation#quick-writing-the-validation-logic
DB::table('inv_codes')->where('code', $request->code)->delete();
You can read more at: https://laravel.com/docs/8.x/queries#delete-statements
Ideally you would create a table to hold the invitations and an accompanying Eloquent model. On register, you can check if the invitation code the user entered is valid by using a couple of ways.
Manually
Invitation::where('code', request()->inv_code)->firstOrFail();
Validation
request()->validate([
'inv_code' => ['exists:inv_codes,code'],
]);
In either case, you need to fetch the invitation and then delete it after registering the user.
$invitation->delete();

Adding custom (guarded) field to Laravel 5.3 Auth

I am trying to add a custom field 'role' to Laravel 5.3 User Auth. The role will determine whether the user is admin amongst other roles and so because the Auth scaffolding uses mass assignable attributes, there is a vulnerability.
Therefore I have changed my User model to:
protected $guarded = [
'role'
];
RegisterController I have added my custom fields (a default user will have the role = customer);
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'facebook_id' => $data['facebook_id'],
'linkedin_id' => $data['linkedin_id'],
'avatar' => $data['avatar'],
'token' => $data['token'],
'role' => 'customer',
I am getting this error message:
SQLSTATE[HY000]: General error: 1364 Field 'role' doesn't have a default >value (SQL: insert into users (name, email, password, >facebook_id, linkedin_id, avatar, token, updated_at, >created_at) values (name, name#domain.co.uk, hashed password, , , , , >2017-01-20 17:21:16, 2017-01-20 17:21:16))
Can't for the life of me figure it out.
I was thinking that maybe I don't use the mass assignable input, but I have a feeling that may mess up the rest of the Auth scaffold.
Thanks for any help
An easy way to set the default role is to actually define it in the model
class User extends Model
{
protected $attributes = [
'role' => 'customer',
];
protected $guarded = [
'role'
];
//...
Now when you use the create method and don't pass the the 'role' attribute, the insert will use the value 'customer'
In your migration for the users table where you add the role field, you either need to set the field as nullable, or give it a default value, so that when you mass assign without it, the database knows how to deal with that field.
Schema::table('users' function(Blueprint $table){
$table->string('role')->default('customer');
});
or
Schema::table('users' function(Blueprint $table){
$table->string('role')->nullable();
});
if your code can deal with a null role value.

Password with FirstOrCreate

I want to use FirstOrCreate for a new user.
Like that:
$user = User::FirstOrCreate([
'name' => $request->username,
'email' => $request->email,
'password' => User::generatePassword()
]);
generatePassword() just generate a random 8 chars string string.
Thing is is doesn't work because it's looking for a user that has this password value.
So, it works when there is no user with this email, but when there is it gives me a constraint error.
What should be the cleanest way to fix it???
You've made a grammatical error. ::firstOrCreate searches based on criteria provided, and if it's not found, it will create the database entry and return the model with that data. ::firstOrNew does that without saving the model automatically.
So, you would want this.
$user = User::firstOrNew([
'email' => $request->email,
]);
We do not include name or password because we are not checking to see if Josh with josh#stackoverflow.com using password foobar123 exists, we just want to know if josh#stackoverflow.com has an account.
Your controller logic seems a bit weird because we would first want to validate that information before creating a model, but I'll roll with it.
$user = User::firstOrNew([
'email' => $request->email,
]);
// This model does not have a DB record.
if (!$user->exists)
{
$user->name = $request->username;
$user->password = User::generatePassword();
$user->save();
}
return $user;
With that logic, we find a record based on email. If the record exists, we pass it. If it does not, we assign it a username and generate a password for it before creating the record and then pass it.

Cartalyst Sentinel Laravel - How do you create roles?

Im new to Cartalyst Sentinel and this concept of ACL. I've managed to create a user, perform activation and login and logout.
I'd like to take my learning to the next level. I would like 2 types of Users on this laravel app. 1 is Administrator another is Subscriber. I'm assuming my account creation method should by default create the user a subscriber.
public function postCreate() {
/* Validation */
$validation = Validator::make(Input::all(), [
'email' => 'required|email|max:50|unique:users',
'username' => 'required|min:3|max:20|unique:users',
'password' => 'required|min:6',
'password_repeat' => 'required|same:password',
]);
if ($validation->fails()) {
return Redirect('login')->withErrors($validation)->withInput();
} else {
$credentials = Input::all();
$user = Sentinel::register($credentials);
$activation = Activation::create($user);
$activation_code = $activation->code;
if ($user) {
Mail::send('emails.auth.activate', ['link' => URL::route('account-activate', [$user->id, $activation_code]), 'username' => $user->username], function($message) use ($user) {
$message->to($user->email, $user->username)->subject('Activate your account');
});
return Redirect::route('home')->with('global', 'Thank you for registering! We have sent you an email to activate your account');
}
}
}
Do i alter the code like so
$user = Sentinel::register($credentials);
$user = Sentinel::findById(1);
$role = Sentinel::findRoleByName('Subscribers');
$role->users()->attach($user);
The thing is i have not even created any roles to begin with. Where do we write that functionality? Right now i have the following Controllers
AccountController - handles activation
AuthController - handles login/logout
RegistrationController - handles registration of user
RolesController - i've not written anything inside here yet. Im a bit lost.
Please guide me. Any help is greatly appreciated.
You do not need to do a search for your user if you already registered them, the register method returns the user.
You can do the following to attach a role to a user:
$user = Sentinel::register($credentials);
$role = Sentinel::findRoleByName('Subscribers');
$role->users()->attach($user);
// OR
$user->roles()->attach($role);
you have both a user and a role object and they have a many to many relation so it doesn't matter which one you use.
You will need to create a db seeder or a method to create your permissions. But to create your Subscribers Role you will need to do the following:
Sentinel::getRoleRepository()->createModel()->create([
'name' => 'Subscribers',
'slug' => 'subscribers',
'permissions' => [
'user.view' => true,
'user.delete' => false,
// any other permissions you want your Subscribers to have
]
]);
A similar call can build your Administrator roles as well.
Your Roles Model and Controller are already built for you, you just need to access them through Sentinel, which you already have Sentinel::findRoleByName('Subscribers'); call.
Cartalyst has some pretty decent documentation about setting up roles and permissions for your users:
https://cartalyst.com/manual/sentinel#roles
https://cartalyst.com/manual/sentinel#permissions
It's just a matter of figuring out what you want each role to do or not do.
Also, you can set specific permissions per user to override the role permissions.

Resources