Laravel unique validation rule with except not working - laravel

Laravel unique validation rule with except column not working on update, what's wrong in my code ?
public function update(Request $request, Article $article)
{
abort_if($article->user_id !== $request->user()->id, 403);
$article = $request->user()->articles()->update($request->validate([
'title' => [
'required',
Rule::unique('articles', 'title')->ignore($article->id)
],
'content'=>'required|min:90',
]));
return redirect('articles/'.$article->id)->withSuccess('Article saved.');
}
Error : The title has already been taken.
Laravel version : 6.4.0
Thanks for help

You can pass the entire instance of article to validate like:
Rule::unique('articles')->ignore($article);
Because you are already saying what column to check.
https://laravel.com/docs/6.x/validation

Remove title from
Rule::unique('articles', 'title')->ignore($article->id)
to
...
$article = $request->user()->articles()->update($request->validate([
'title' => [
'required',
Rule::unique('articles')->ignore($article->id)
],
'content'=>'required|min:90',
]));
...
Hope this helps
more info, check rule-unique

If you run the update on $request->user()->articles() you will update all of the user's articles. If the user only has 1 article then it should work just fine, however if there are more then this will result in data being overwritten.
Instead do:
$article->update($request->validate([
'title' => [
'required',
Rule::unique('articles', 'title')->ignore($article->id)
],
'content'=>'required|min:90',
]));

Related

The unique Rule validation is not applied

I am using laravel 9.
And I have this very simple validation rule (form request validation):
public function rules()
{
return [
'first_name' => 'required|max:50',
'last_name' => 'required|max:50',
'email' => [
'email',
Rule::unique('unknown_table')->where(function ($query) {
return $query->where('library_id', $this->library->id);
})
],
.......
What I do not understand is why my post is working with this table name "unknown_table", because this table really does not exist. I expected an exception but nothing happens !
Is this rule correctly written ?
I have understood my error. The "email" validation was twice in the rule array ! And it was the last one which was used of course.

Creating two relationships from the same controller method in laravel

I am trying to allow users to post pictures and comment on pictures. The pictures are related to the users through a one to many relationship and the comments are related to the pictures through a one to many relationship. I am now trying to simultaneously relate both users and pictures to comments whenever a comment is made. Currently, I am able to relate comments to either the picture or the user but not both.
Below is the controller method which handles comment uploads:
public function postComment(Request $request, $picture_id)
{
$this->validate($request, [
"comment" => ['required', 'max:1000'],
]);
$picture = Picture::find($picture_id);
$picture->status()->create([
'body' => $request->input('comment'),
]);
Auth::user()->statuses()->update([
'body' => $request->input('comment'),
]);
return redirect()->back();
}
I have tried creating one relationship and then creating the other relationship using update(). This did not work and resulted in the value remaining null.
Thank you for your help.
If i am understanding your database model correctly, when creating the status model for your picture all you need to do is to also include the user id like so:
public function postComment(Request $request, $picture_id)
{
$this->validate($request, [
"comment" => ['required', 'max:1000'],
]);
$picture = Picture::find($picture_id);
$picture->status()->create([
'body' => $request->input('comment'),
'user_id' => Auth::id()
]);
return redirect()->back();
}
Also make sure to add user_id to the $fillable property in the Status model to allow it to be assigned through the create method
protected $fillable = [
'body', 'user_id',
];
This should link the status you just created to both the picture and user class. You can then retrieve it elsewhere with something like Auth::user()->statuses

Right way to handle this situation using Laravel validation

i am new in Laravel and I would like to have some directive on how to handle this situation.
I have two entities: Ad and Nomination. Ad can have many Nominations.
In a controller i receive two external inputs: [ad_id] and [nomination_id] both required.
What i have to do with these two inputs is:
Check if [ad_id] is an existing Ad entity and his attribute "active" is true.
Check [nomination_id] is an existing Nomination entity.
Only if [ad_id] was an existing Ad and [nomination_id] was an existing Nomination check if this Nomination belongs to this Ad.
Can you show me an example about how to manage this using only validation class?
You can write your validation rules like this
public function rules()
{
return [
'ad_id' => [
'bail',
'required',
Rule::exists('ads')->where(function ($query) use ($request) {
$query->where([
['active' => 1],
['id' => $request->ad_id]
]);
}),
],
'nomination_id' => [
'bail',
'required',
Rule::exists('nominations')->where(function ($query) use ($request) {
$query->where([
['ad_id' => $request->ad_id],
['id' => $request->nomination_id]
]);
}),
],
];
}
Assuming you have ads and nominations are tables name and primary key field is id and ad_id as foreign key in nominations table.
It's pretty straightforward - you can write validation rules just as you listed them in your question:
$validator = Validator::make($request->only('ad_id', 'nomination_id'), [
'ad_id' => 'required|exists:ads,id,active,1',
'nomination_id' => 'required|exists:nominations,id,ad_id,' . $request->ad_id,
]);
if ($validator->fails()) {
...
}
$inputAd = <some_value>;
$inputNomination = <some_value>;
$nomination = Nomination::where(['id' => $inputNomination])->with(['ads'])->first();
if(!$nomination || !($nomination->ad_id == $inputAd)) {
// not the same
}
// same
To validate the ad_id and nomination_id, you can use laravel in rule.
FormRequest Class
public function rules()
{
return [
'ad_id' => [
'required',
Rule::in(Ad::where('active', true)->pluck('id')->toArray()),
],
'nomination_id' => [
'required',
Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()),
],
];
}
The Rule::in(Ad::where('active', true)->pluck('id')->toArray()), rule will check if the ad_id is present in the array of ids of Ad which have active field is true.
The Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()), rule will check if the nomination_id is present in the array of ids of Nomination which is related to Ad.

Laravel, Forcing A Unique Rule To Ignore A Given ID

I am following the instructions from the Laravel Documentation but I can't seem to make the rule work. Basically, I want to add a unique rule for both email and username fields for updating the user profile, but it doesn't seem to work. Am I missing something?
Here is the function for updating user credentials
public function updateCredentials(Request $request, User $user)
{
Validator::make($request->all(), [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'username' => [
'required','string','min:4','max:255',
Rule::unique('users')->ignore($user->id),
],
'email' => [
'required','string','email','max:255',
Rule::unique('users')->ignore($user->id),
],
'asdf' => 'required',
'type' => 'required',
])->validate();
}
Thanks in Advance!
If you want to update user profile,without changing his id,you dont need to set specific rule for that.
Without explicitly setting the new user id,it should stay the same.
You can just name the data you want to change like this:
$user->name = request('name');
$user->lastname = request ('lastname);
$user->email = request('email');
...
$user->save();
session()->flash('message','Profile update complete!');
return redirect('/home');
Doing this the data you want will update,but the id will stay the same.
Seems to be some bug.
Adding filed name worked for me:
Rule::unique('users')->ignore($user->id, 'users')

Laravel 5.5 Form Validation Request unique Rule no Data

Currently updating Laravel from v5.2 to 5.5 and can't figure out how I get the "unique" rule working on update.
This is my rule that works nice on Laravel 5.2
public function rules()
{
$retVal = [
'username' => 'required|alpha_dash|min:4|max:30',
'password' => 'min:6|confirmed',
'password_confirmation' => 'min:6',
'email' => 'required|email|unique:users,email,' . $user->id,
'roles_list' => 'required',
];
if (stristr($this->get('username'), '#'))
{
$retVal['username'] = 'required|email';
}
return $retVal;
}
But now in Laravel 5.5 I get always an "email unique"-error on update. When I type in the user-id manually it works. Like described in the Laravel docs it should work:
https://laravel.com/docs/5.5/validation#form-request-validation
I have no clue how to get the $user object accessible in my form request.
Thank you very much in advance for assist !
Your $user variables seems null.
If you're trying to retrieve the currently authenticated user in your Request class, you can try this:
$user = $this->user();
Next, you have to change your email rules a bit:
'email' => 'required|email|unique:users,email,' . ($user ? $user->id : 0),

Resources