Laravel unique validation with softdeletes data - php

I want to use Laravel Unique validator with the implementation of softdeletes. I've been try many times but it produce an error like this. What should i do? Thanks in advance. Here's my code example.
public function store(Request $request)
{
$request->validate([
'nama' => 'required',
'nim' => [
'required',
'size:10',
Rule::unique('students')->where(function ($query) {
return $query->where('deleted_at', NULL);
})
],
'email' => 'required|email',
]);
Student::create([
'major_id' => $request->major_id,
'nama' => $request->nama,
'slug' => Str::of($request->nama)->slug('-'),
'nim' => $request->nim,
'email' => $request->email,
]);
return redirect('/students')->with('status', 'Success');
}

The error you're getting is from a constraint in your database. Nothing you can do in the code can counter that. The database doesnt care for soft delete.
You need to remove the constraint from the database first, then use your solution or the one from this post check-if-name-is-unique-among-non-deleted-items-with-laravel-validation
To remove the constraint, run this query
ALTER TABLE students DROP CONSTRAINT students_nim_unique;
The best practice would be to create a new migration running this query. Carefull for the down() method, you will not be able to put back the constraint if there are dupplicate nim in the table (soft deleted or not)

Related

Laravel Jetstream - How to join a default team at registration

I am trying to change Laravel Jetstream's logic in order to join a default team at registration rather than create a personal team. I found the method that does this:
public function create(array $input)
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '',
])->validate();
return DB::transaction(function () use ($input) {
return tap(User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]), function (User $user) {
$user->currentTeam = Team::find(1); # SQLSTATE[42S22]: Column not found: 1054 Unknown column 'currentTeam' in 'field list'
$user->save();
});
});
}
The issue here is that currentTeam seems to be an created after the database level and not a column in the Database itself. The documentation says that currentTeam returns the Team model but doesn't say how to update the current users team programmatically.
I can see I can manually use a DB query to insert a row into the team_user table but there must be a method to do this.
return DB::transaction(function () use ($input) {
return tap(User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]), function (User $user) {
DB::table('team_user')->insert(['user_id' => $user->id, 'team_id' => 1, 'role' => 'rfn']);
$user->current_team_id = 1;
});
});
Any help would be appreciated, I understand this will be reliant on this team always existing in the Database but further measures will be implemented so it cannot be removed.
After some tinkering with a local Laravel version, this is was I came up with. This assumes the team you wanna add the user to is already created somehow, possibly through a seeder, or created manually. The file you need to edit is app/Actions/Fortify/CreateNewUser.php, namely the createTeam method.
Instead of creating a new team, we want to grab a team from the database, attach it to the newly registered user and then make that now attached team the users current team.
protected function createTeam(User $user)
{
$team = Team::first();
$user->teams()->attach($team);
$user->switchTeam($team);
}
The reason we first need to attach the team first is that switchTeam checks if a user belongs to that team if it doesn't it returns false and doesn't switch to the new team. By attaching the team first we make the user belong to that team before we can actually switch to it as the current team.
you can assign role as well in above answer of #KimHallberg as below
$team = Team::first();
$user->teams()->attach($team, array('role' => 'editor'));
$user->switchTeam($team);

How to properly update a model on laravel? Method Illuminate\Database\Eloquent\Collection::update does not exist

I made a page for a user to update his company information, all companies default values are null, when a user is created. When a user fills the information, i get this error:
Method Illuminate\Database\Eloquent\Collection::update does not exist
I am sure this error is because of my CompanyController#edit
public function edit(Request $request)
{
$this->validate($request, [
'company_name' => 'alpha|max:50',
'phone' => 'integer|max:50',
'gst_hst_number' => 'integer|max:50',
'country' => 'alpha|max:50',
]);
$companies = Company::where('id', Auth::user()->id)->get();
$companies->update([
'company_name' => $request->input('company_name'),
'phone' => $request->input('phone'),
'gst_hst_number' => $request->input('gst_hst_number'),
'country' => $request->input('country')
]);
return redirect()->route('company.index')->with('info', 'Company information was updated.');
}
I am stuck quite some time on this issue, would gladly apriciate help and information how to properly update my company models fillable fields.
‌As the error message says, you are using the update method on a collection, you have to change the select query to this:
$companies = Company::where('id', Auth::user()->id)->first();
Because the get() method returns a collection, not a single record.
Try this. ->get() is for multiple collections here you can directly update your records.
$companies = Company::where('id', Auth::user()->id)->update([
'company_name' => $request->input('company_name'),
'phone' => $request->input('phone'),
'gst_hst_number' => $request->input('gst_hst_number'),
'country' => $request->input('country')
]);;
Your using update method on collection, but collection doesn't have update method,
what you need is remove the get(), so you can use update method on eloquent builder:
$companies = Company::where('id', Auth::user()->id);
$companies->update([
'company_name' => $request->input('company_name'),
'phone' => $request->input('phone'),
'gst_hst_number' => $request->input('gst_hst_number'),
'country' => $request->input('country')
]);

How to call variables in controller Laravel

I'm trying to use Auth::user()->id; and post them with another model under 'user_id' so I don't have to manually give users a 'user_id'.
I've checked and included the required files and I'm getting the users "id" from Users Table
$user_id = Auth::user()->id;
echo $user_id; //this is returning right user "id"
I'm having trouble calling variables and posting it to DB in controller functions any help would be fine.
public function store(Request $request)
{
$user_id = Auth::user()->id;
$this->validate($request, [
'token1' => 'required',
'token2' => 'required'
]);
$tokens = new Tokens([
'user_id' => $user_id,
'token1' => $request->get('token1'),
'token2' => $request->get('token2')
]);
$tokens->save();
return view('/home');
}
Post the User "id" from User table into Tokens table's "user_id" so I can work with models
Getting this error:
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL
constraint failed: tokens.user_id (SQL: insert into "tokens"
("token1", "token2", "updated_at", "created_at") values (asddsadf,
sdfasdf, 2019-09-24 11:53:57, 2019-09-24 11:53:57))
My migration is:
$table->bigIncrements('id');
$table->integer('user_id');
$table->string('token1');
$table->string('token2');
$table->timestamps();
You should avoid filling the user_id in this way.
The error is thrown because user_id is not a fillable property. But the correct way to handle this is with the relationships.
So I suppose that Tokens has a belongsTo relation because of its user_id foreign key (that anyway should be an unsignedInteger column) and in your model you have something like:
public function user() {
return $this->belongsTo(User::class)
}
If you have a look at the offical documentation you will see that you should change your code in this way:
public function store(Request $request)
{
$this->validate($request, [
'token1' => 'required',
'token2' => 'required'
]);
$tokens = new Tokens([
// 'user_id' => $user_id, This is useless
'token1' => $request->get('token1'),
'token2' => $request->get('token2')
]);
// With this method you're going to set the user_id column
$token->user()->associate(auth()->user());
$tokens->save();
return view('/home');
}

Login with additonal condition laravel 5.3

I am trying to authenticate a user with the obvious email and password and also if the ban_status is set to 0 in the database.
I have had a look at the newest laravel docs and I have tried it this way in the AuthenticateUsers.php
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required', 'password' => 'required', 'ban_status' => '0',
]);
}
This does not do anything as far as I can tell and will log in the user regardless whether there ban status is 0 or not, where should I be doing this extra condition?
Thanks
In your code you have:
$this->validate($request, [
$this->username() => 'required', //????
'password' => 'required',
'ban_status' => '0',
]);
I'm not sure why you have 'required' there by itself, so I was thinking something along the lines of this:
$user = $this->username();
$this->validate($request, [
$this->username() => 'email' => 'bail|required|email|exists:dbnamehere.tablenamehere|min:7', //can also be username
'password' => 'bail|required|min:8',
'ban_status' => ['required',
Rule::unique('users_table_name_here')->where(function ($query) use ($user) {
$query->where(['account_id',$user],
['ban_status', 0])]
})
]);
This may not work right off so you might have to tinker with it a little bit but it makes nice use of Laravel's Eloquent models. So hopefully this points you in the right direction. Also be sure to change table names and field names to whats in your database.
Happy Coding =)
Reference:
https://laravel.com/docs/5.3/validation

How to perform validation when updating a unique field using Http\Request in Laravel

I have a customers table that I use a CustomerRequest to validate the fields, through the use of the rules function. The table has an email field which is required and is unique. This works fine when I create the customer, however when I update the customer info (let's say I got their last name spelled wrong) my request fails because the email address is already in the database.
Here is my CustomerRequest:
public function rules()
{
return [
'givenname' => 'required',
'surname' => 'required',
'email' => 'required|unique:customers,email',
];
}
I would like to reuse the CustomerRequest for all of the customer vaildation, how can I go about doing this?
You need to check here for request type as well as customer id for update and then return rules according to request. Something like this
public function rules(Request $customer_request)
{
return [
'givenname' => 'required',
'surname' => 'required',
'email' => 'required|unique:customers,email,'.$customer_request->get('customer_id'),
];
}

Categories