When user creation, assign role_id with UUID - laravel

I have a UUID system on my application and when I register a user I have to indicate the rank_id, only I don't know its ID as it is generated from a UUID.
So I use a query but it seems to me disgusting.
Do you have another solution?
I thought about not putting a UUID on the rank table to make it easier but I don't know if it's a good idea to mix uuid and classic id
User::create([
'rank_id' => Rank::select('id')->where('title', 'User')->first()->id,
'username' => $request->input('username'),
'email' => strtolower($request->input('email')),
'password' => Hash::make($request->input('password')),
]);
Schema::create('users', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->foreignUuid('rank_id')->constrained('ranks');
$table->string('username');
$table->string('email');
$table->string('password');
$table->integer('status')->default(0);
$table->rememberToken();
$table->timestamps();
});
Schema::create('ranks', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('title');
$table->timestamps();
});

For easier access, create a helper class or function and use it.
For example create a directory called app\Helpers and inside create a class called RankHelper. The implementation can be like below:
namespace App\Helpers;
use App\Models\Rank;
class RankHelper
{
public static function getIdByName(string $name): string
{
if (!$rank = Rank::select('id')->where('title', $name)->first()) {
throw new \Exception("No rank with this name found.");
}
return $rank->id;
}
}
Then inside your user creation logic just use it like:
User::create([
'rank_id' => RankHelper::getIdByName('User'),
'username' => $request->input('username'),
'email' => strtolower($request->input('email')),
'password' => Hash::make($request->input('password')),
]);

Related

Laravel Many to Many attach?

I'm trying to create or attach data to table called "user_votes", but I dunno why the connections between "Vote" and "User" doesn't work.
user_votes table
Schema::create('user_votes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->bigInteger('vote_id')->unsigned();
$table->string('name');
$table->string('page', 100)->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('vote_id')->references('id')->on('votes');
});
Vote model:
public function user_votes()
{
return $this->belongsToMany(User::class, 'user_votes');
}
User model:
public function user_votes()
{
return $this->belongsToMany(Vote::class, 'user_votes');
}
store controller:
auth()->user()->user_votes()->attach([
'name' => $option->name,
'page' => $option->page
]);
Thanks for any ideas.
Please try the below code hope it will help you.
$voteId = 1;
auth()->user()->user_votes()->attach($voteId => [
'name' => $option->name,
'page' => $option->page
]);

SQLSTATE[HY000]: General error: 1364 Field 'img' doesn't have a default value (SQL: insert into `users`

What is the reason for the error? This has happened after changing the code of the default when registering. Please take me
SQLSTATE[HY000]: General error: 1364 Field 'img' doesn't have a default value (SQL: insert into `users` (`username`, `password`, `role`, `updated_at`, `created_at`) values (aaaaaaa, .....G, user, 2019-01-14 16:40:05, 2019-01-14 16:40:05))
protected function validator(array $data)
{
return Validator::make($data, [
'username' => 'required|string|check_username|max:255|unique_username',
'password' => 'required|string|min:6',
'captcha'=>'required|captcha'
],[],[
'username'=>'user',
'password'=>'pass',
'captcha'=>'cap',
'img'=>'profile',
'fnamelname'=>'fnamelname',
]);
}
protected function create(array $data)
{
return User::create([
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role'=>'user'
]);
}
Try this:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username')->unique();
$table->string('password');
$table->string('img')->default(1);
$table->string('fnamelname');
$table->string('role');
$table->rememberToken();
$table->timestamps();
});
}
EDIT:
This is a better version
$table->string('img')->nullable();
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username')->unique();
$table->string('password');
$table->string('img');
$table->string('fnamelname');
$table->string('role');
$table->rememberToken();
$table->timestamps();
});
}
/**
If the img field is optional, your data model should reflect that intent clearly.
In your migration:
$table->string('img')->nullable();
will set this column as nullable, thus you can create a record without setting a value explicitly.
See https://laravel.com/docs/5.0/schema#adding-columns
Also, you'd better use a BLOB type instead of a string to store binary content like images. But that's another topic.

Creating a item with multiple relations in 1 call

So I have a project table:
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('name');
$table->string('reference')->nullable();
$table->date('started')->nullable();
$table->date('ended')->nullable();
$table->string('industry')->nullable();
$table->string('operatives')->nullable();
$table->timestamps();
$table->softDeletes();
});
And I have an hours table:
Schema::create('hours', function (Blueprint $table) {
$table->increments('id');
$table->string('hours');
$table->date('date')->nullable();
$table->text('notes')->nullable();
$table->integer('project_id');
$table->integer('user_id');
$table->softDeletes();
$table->timestamps();
});
Now, is there anyway to create an association with both the project_id and user_id in one call?
I know I can do the following (adding the user_id to the hours):
$hours = [
'hours' => $request->hours,
'date' => $request->date,
'operatives' => $request->operatives,
'notes' => $request->notes,
'user_id' => auth()->user()->id,
];
$create = $project->hours()->save(new $this->hour($hours));
But I am trying to do something like so:
$hours = [
'hours' => $request->hours,
'date' => $request->date,
'operatives' => $request->operatives,
'notes' => $request->notes,
];
$create = $project->hours()->save(auth()->user()->save($hours));
Both user and project have the same hours relation in their classes:
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function hours(): HasMany
{
return $this->hasMany(Hour::class);
}
Is this possible, if so, how would I go about doing it?
I think the best way to handle this would be to separate the saving of Hours as an independent instance of the model and then sync it with both like so:
$hour = Hour::create($hours);
$project->hours()->syncWithoutDetaching([$hour->id]);
$user->hours()->syncWithoutDetaching([$hour->id]);

Does not change default value in mysql (laravel 5,5)

this is my code in users tabel (migrations)
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('level')->default('user');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
when I want to change level manually like below code
return User::create([
'level' => 'admin',
'name' => 'emad',
'email' => 'emad#gmail.com',
'password' => bcrypt('123456')
]);
In the level field, the same user value is saved and admin dosent save.
I do not know why?
Judging from the little code here, i would say you haven't added the level column to the fillable model variable.Like so:
protected $fillable = ['level','any_other_field_you_want_to_assign'];
Add this line of code to the top of your User model class
Check the documentation here

Laravel 5 How to add multiple foreign key constraints to a User on creation?

I now know that I can create a User using the haveMany relationship between a Region and User by doing this:
$region = Region::find($data['region_id']);
$region->users()->create([
'username' => $data['username'],
'email' => $data['email'],
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'password' => bcrypt($data['password']),
]);
But what if there are multiple foreign keys, how do you create a user without making them fillable for more than 1 foreign key constraint? What if there were 3 or 4?
Example of the relationships setup in the different models:
Region hasMany Users, or
User belongsTo a Region
Location hasMany Users, or
User belongsTo a Location
A stripped down version of my migration looks like this if it helps to understand the relationships better:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('region_id')->unsigned();
$table->integer('location_id')->unsigned();
$table->timestamps();
$table->foreign('region_id')
->references('id')
->on('regions');
$table->foreign('location_id')
->references('id')
->on('locations');
});
Schema::create('regions', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 100);
$table->timestamps();
});
Schema::create('locations', function (Blueprint $table) {
$table->increments('id');
$table->string('street_address', 100);
$table->string('city', 50);
$table->string('province', 50);
$table->string('country', 50);
$table->string('postal_code', 10);
$table->timestamps();
});
Example of Region and Location Models:
/**
* Region may have many users.
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users()
{
return $this->hasMany('App\User');
}
/**
* Location may have many users.
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users()
{
return $this->hasMany('App\Location');
}
I assume you have a model for Region and Location. Each of your region has an id and location has an id, then just add
$this->hasMany('where your Region model is', 'region_id', 'id');
$this->hasMany('where your Location model is', 'location_id', 'id');
to your User model
Reference: http://laravel.com/docs/5.0/eloquent#one-to-many
Edit: You can also do in any of your model
if ($this->create()) {
return (new Model())->create(the params you need in another model);
}

Resources