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.
I'm using the validation for the employee records during an update. There are some fields which should be unique. But during an update of the employee records, the validation for the unique field is being done. I have researched and tried out the solution as well.
But I'm getting this error:
Error Code : 904 Error Message : ORA-00904: "ID": invalid identifier
Position : 71 Statement : select count() as aggregate from
"EMPLOYEES" where " EMAIL" = :p0 and "ID" <> :p1 Bindings :
[ad#sdfdsf.com,3336] (SQL: select count() as aggregate from
"EMPLOYEES" where " EMAIL" = ad#sdfdsf.com and "ID" <> 3336)
Here is my attempt for the solution:
public function update(Request $request, int $employee_id) {
$this->validate ( $request, [
'first_name' => "required|max:220|regex:/[a-z]/",
'middle_name' => "max:120",
'last_name' => "required|max:220|regex:/[a-z]/",
'email' => "required|unique:employees, email, $employee_id|regex:/[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}/",
'home_phone' => "unique:employees,home_phone, $employee_id|numeric|regex:/^[09][0-9]{8,9}$/",
'mobile' => "unique:employees,mobile, $employee_id|numeric|regex:/(9)[0-9]{9}/",
'job_id' => 'required',
'department_id' => 'required',
'group_id' => 'required',
'node' => 'required',
'branch' => 'required',
'username' => "required|unique:employees,username, $employee_id|regex:/[A-Za-z0-9][.][A-Za-z0-9]/",
'exchange_username' => "required|unique:employees,exchange_username, $employee_id|regex:/[A-Za-z0-9][.][A-Za-z0-9]/",
'extension' => "unique:employees,extension, $employee_id|numeric|regex:/[0-9]{4}/",
] );
Employee::where ('employee_id', $employee_id )->update ( $request->only ( [
'first_name',
'middle_name',
'last_name',
'email',
'address',
'home_phone',
'mobile',
'job_id',
'department_id',
'group_id',
'branch',
'node',
'name',
'username',
'type',
'exchange_username',
'toggle_ivr_access',
'extension',
'attributed_team',
'cable_team_id',
'disable',
] ) );
Session::flash ( 'message', 'The Employee is Successfully Updated.' );
return redirect ()->route ( 'employees.index' );
}
Forcing A Unique Rule To Ignore A Given ID:
Sometimes, you may wish to ignore a given ID during the unique check.
For example, consider an "update profile" screen that includes the
user's name, e-mail address, and location. Of course, you will want to
verify that the e-mail address is unique. However, if the user only
changes the name field and not the e-mail field, you do not want a
validation error to be thrown because the user is already the owner of
the e-mail address.
To instruct the validator to ignore the user's ID, we'll use the Rule
class to fluently define the rule. In this example, we'll also specify
the validation rules as an array instead of using the | character to
delimit the rules:
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
I figured out the mistake and successfully find out the solution. Here is the working solution in case anyone is facing the similar problem. I had to pass the employee_id of the single user whereas I was passing the employee_id of the multiple users.
public function update(Request $request, int $employee_id) {
$this->validate ( $request, [
'first_name' => "required|max:220|regex:/[a-z]/",
'middle_name' => "max:120",
'last_name' => "required|max:220|regex:/[a-z]/",
'email' => "required|unique:employees,email,".$employee_id.',employee_id|regex:/[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}/',
'home_phone' => "unique:employees,home_phone,$employee_id,employee_id|numeric",
'mobile' => "required|unique:employees,mobile,$employee_id,employee_id|numeric",
'job_id' => 'required',
'department_id' => 'required',
'group_id' => 'required',
'node' => 'required',
'branch' => 'required',
'username' => "required|unique:employees,username,".$employee_id.',employee_id|regex:/[A-Za-z0-9][.][A-Za-z0-9]/',
'exchange_username' => "required|unique:employees,exchange_username,".$employee_id.',employee_id|regex:/[A-Za-z0-9][.][A-Za-z0-9]/',
'extension' => "required|unique:employees,mobile,$employee_id,employee_id|numeric|regex:/[0-9]{4}/",
] );
Employee::where ('employee_id', $employee_id )->update ( $request->only ( [
'first_name',
'middle_name',
'last_name',
'email',
'address',
'home_phone',
'mobile',
'job_id',
'department_id',
'group_id',
'branch',
'node',
'name',
'username',
'type',
'exchange_username',
'toggle_ivr_access',
'extension',
'attributed_team',
'cable_team_id',
'disable',
] ) );
Session::flash ( 'message', 'The Employee is Successfully Updated.' );
return redirect ()->route ( 'employees.index' );
}
I have 2 tables within one function that I'd like to save data to. One is the Users table, and the second one is a Clinic table.
My user's table is currently working correctly, but I'm unsure if it's 'best practice':
$user = User::create([
'name' => Str::title($request->get('name')),
'email' => $request->get('email'),
'password' => bcrypt($request->get('password'))
])
->clinic()->create($request->only([
'name' => Str::title('clinic_name'),
'telephone',
'address_1',
'address_2',
'city',
'postcode'
]));
My problem occurs at the 'name' column of the Clinic table. It just doesn't save it, even though it's in the $fillable array in my Clinic column:
protected $fillable = ['user_id', 'name', 'telephone'', 'address_1',
'address_2', 'city', 'postcode'];
I have attempted to 'Chain' the methods together, as I want to save the 'user_id' within the Clinic table because they're related.
Many thanks for your help.
You're overriding the name key in your $request->only() call:
$user = User::create([
'name' => Str::title($request->get('name')),
'email' => $request->get('email'),
'password' => bcrypt($request->get('password'))
])->clinic()->create($request->only([
'name' => Str::title('clinic_name'), // This is overriding your 'name' field.
'telephone',
'address_1',
'address_2',
'city',
'postcode'
]));
If you want to run Str::title() over the requests clinic_name, you'll need to assign the attributes manually like so:
$user = User::create([
'name' => Str::title($request->get('name')),
'email' => $request->get('email'),
'password' => bcrypt($request->get('password'))
])->clinic()->create([
'name' => Str::title($request->get('clinic_name')),
'telephone' => $request->get('telephone'),
'address_1' => $request->get('address_1'),
'address_2' => $request->get('address_2'),
'city' => $request->get('city'),
'postcode' => $request->get('postcode'),
]);
Note: Just as a tip, you can also just retrieve request input as a property like so:
->create([
'name' => $request->name // Performs $request->get('name').
])
You can't have 'name' => Str::title('clinic_name') when using create(), it must be a single key as 'name'.
You can use the following before creating the user:
$request->replace('name' => Str::title('clinic_name'));
I have three tables users,roles and role_user I want to insert record on that tables with minimum query using eloquent. My current code of insertation
User::create([
'name' => 'admin',
'email' => 'admin#test.pk',
'password' => bcrypt('admin123'),
]);
//create default roles while installation of application
$roles = array(
array('name' => 'admin', 'display_name' => 'Administrator User', 'description' => 'system admin user'),
array('name' => 'registered', 'display_name' => 'Registered User', 'description' => 'free user')
);
foreach ($roles as $key => $role)
{
Role::create($role);
}
//relation between users and roles
User::find(1)->roles()->attach(1);
In above code i am creating a user then creating two roles then inserting record in pivot table(role_user). I want to know is there any otherway that i insert the record on these table at same time with one eloquent query Or there is anyother better way?
Unfortunately it is not possible to insert rows in more than one table at the same time.
Best what I can think of is that:
$user = User::create([
'name' => 'admin',
'email' => 'admin#test.pk',
'password' => bcrypt('admin123'),
]);
//create default roles while installation of application
$roles = [
['name' => 'admin', 'display_name' => 'Administrator User', 'description' => 'system admin user'],
['name' => 'registered', 'display_name' => 'Registered User', 'description' => 'free user']
];
Role::insert($roles);
//relation between users and roles
$user->roles()->attach(1);
With this example You save two queries:
Laravel calls only one insert query, instead of two when inserting roles;
Laravel does not select User from database - using variable instead;
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.