Ignoring the user result input when updating data goes wrong - php

I'm working on an :
edit.blade.php
where users can edit data and the update method of Controller goes here:
public function update(Request $request, $id)
{
$discountCode = DiscountCode::find($id);
$request->validate([
'code' => 'unique:discount_codes,code'.$discountCode->id,
'started_at' => 'required_if:timespan,TRUE',
'ended_at' => 'required_if:timespan,TRUE',
],
...
}
So as you can see the code must be uique in discount_codes table.
So I tried adding :
$discountCode->id
in order to ignore unique validation rule for the current data but it does not work out and returns this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'code15' in
'where clause' (SQL: select count(*) as aggregate from
`discount_codes` where `code15` = GIGvJjp4PM)
15 is my data row id.
So what's going wrong here? How can I solve this issue?

Use Rule::class to create the rule and ignore specific id
use Illuminate\Validation\Rule;
//...
public function update(Request $request, $id)
{
$discountCode = DiscountCode::findOrFail($id);
$request->validate([
'code' => [Rule::unique('discount_codes')->ignore($id)],
'started_at' => 'required_if:timespan,TRUE',
'ended_at' => 'required_if:timespan,TRUE',
],
...
}

Related

General error: 1364 Field 'title' doesn't have a default value while doing update

Hello I faced the following error:
SQLSTATE[HY000]: General error: 1364 Field 'title' doesn't have a default value.
It happens when I try to update amount of views on specific post.
I've just set default value of points while initializing it specified in the model in $attributes table.
Posts table migration:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longText('text');
$table->integer('points');
$table->bigInteger('views');
$table->integer('user_id')->unsigned()->nullable();
$table->integer('is_closed');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
});
}
Post model:
const POINTS = 0;
const VIEWS = 0;
const IS_CLOSED = 0;
protected $attributes = [
'points' => self::POINTS,
'views' => self::VIEWS,
'is_closed' => self::IS_CLOSED,
'title' => null,
'text' => null,
'user_id' => null,
];
protected $fillable = [
'title',
'text',
'user_id',
];
My Service where I try to increment the value of views:
public function incrementPostViews($id)
{
$post = $this->post->findOrFail($id);
$post->views++;
return $post->save();
}
I did use the Request rule but only while creating new post:
public function rules()
{
return [
'title' => ['required', 'max:50'],
'text' => ['required', 'max:1000'],
'user_id' => ['numeric', 'nullable'],
];
}
So by default the points, views and is_closed fields are set to 0 while creating new Post. To be honest I do not have any ideas why it is causing an error.
Update:
In Post model I've changed the $attributes array and added title, text and user_id which default value is set to null. Those three fields stays in $fillable array also. I'm not sure if it's the right way to fix it. If it's not, please correct me.
In the migration there are not changes made.
All changes are visible above.
You declared your title item as required in your table but you didn't declare a default value. And your insert operation doesn't give a value for that column, so it fails.
The easiest way to fix this is probably to declare title as nullable instead.
But if you have a good reason to make it required, you'll have to revisit the way you insert your rows so you can offer a value for that column.
You must create THE post first, once that post has been created you can then update its attributes.
$user = Post::create([
'title' => $request->title,
'text' => $request->text,
'points' => 0,
'views' => 0,
'is_closed' => $request->is_closed,
]);

Laravel exists custom validation rule unable to validate user id with phpunit

I have a validation rule taken from the Laravel Documentation which checks if the given ID belongs to the (Auth) user, however the test is failing as when I dump the session I can see the validation fails for the exists, I get the custom message I set.
I have dumped and died the factory in the test and the given factory does belong to the user so it should validate, but it isn't.
Controller Store Method
$ensureAuthOwnsAuthorId = Rule::exists('authors')->where(function ($query) {
return $query->where('user_id', Auth::id());
});
$request->validate([
'author_id' => ['required', $ensureAuthOwnsAuthorId],
],
[
'author_id.exists' => trans('The author you have selected does not belong to you.'),
]);
PHPUnit Test
/**
* #test
*/
function adding_a_valid_poem()
{
// $this->withoutExceptionHandling();
$user = User::factory()->create();
$response = $this->actingAs($user)->post(route('poems.store'), [
'title' => 'Title',
'author_id' => Author::factory()->create(['name' => 'Author', 'user_id' => $user->id])->id,
'poem' => 'Content',
'published_at' => null,
]);
tap(Poem::first(), function ($poem) use ($response, $user)
{
$response->assertStatus(302);
$response->assertRedirect(route('poems.show', $poem));
$this->assertTrue($poem->user->is($user));
$poem->publish();
$this->assertTrue($poem->isPublished());
$this->assertEquals('Title', $poem->title);
$this->assertEquals('Author', $poem->author->name);
$this->assertEquals('Content', $poem->poem);
});
}
Any assistance would be most appreciated, I'm scratching my head at this. My only guess is that the rule itself is wrong somehow. All values are added to the database so the models are fine.
Thank you so much!
In your Rule::exists(), you need to specify column otherwise laravel takes the field name as column name
Rule::exists('authors', 'id')
Since column was not specified, your code was basically doing
Rule::exists('authors', 'author_id')

Laravel unique rule validator breaking during Validator::make

I am trying to check to see if (a) column(s) is/are unique by using the Rule::unique('table')->where(function($query) use($x) {...}); functionality but when I pass this into my validator I am getting a strange error. What I think is happening is that it is trying to check if a value is equal in the where the statement that I provided but also a column that it THINKS is the unique ID column for the table but it is not so it is breaking.
protected function validator(array $data)
{
$uid = 660000000;
$rule = Rule::unique('member_record')->where(function ($query) use ($uid) {
return $query->where('uniqueID', $uid);
});
return Validator::make($data, [
'fullName' => ['required', 'string', 'min:2'],
'member_id' => [
'bail', 'required', 'Numeric', $rule,
'exists:new_benefits_member,member_id'
],
'email' => ['bail', 'required', 'email', 'confirmed', 'unique:user,email'],
'password' => [
'required', 'string', 'min:8', 'confirmed',
'regex:/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$/'
],
'terms' => ['required']
]);
}
However, then I am getting an error that looks like the following.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'member_id' in 'where clause' (SQL: select count(*) as aggregate from member_record where member_id = 660000000 and (uniqueID = 660000000))
What my only assumption is that when I am passing data into the Validator::make($data... it is trying to compare the $rule with the $data array and it is messing it up. Let me know if you have any fixes that I can try out.
The problem here is that the Rule::unique() function can take 2 parameters as shown below
public static function unique($table, $column = 'NULL')
{
return new Rules\Unique($table, $column);
}
if column is left as 'NULL' then this will default to the name of the key in the validator::make($x, [] <--- array
as shown in this example.
protected function validator(array $data)
{
$uid = 660000000;
$rule = Rule::unique('member_record')->where(function ($query) use ($uid) {
return $query->where('uniqueID', $uid)->orwhere('client_member_id', $uid);
});
$data['foo'] = 0;
$validator = Validator::make($data, [
'foo' => [$rule]
]);
return $validator;
}
results in this response
Column not found: 1054 Unknown column 'foo' in 'where clause' (SQL: select count(*) as aggregate from member_record where foo = 0 and (uniqueID = 660000000 or client_member_id = 660000000))
If you would like to exclude "is equal to" in the first part of the where clause you would perform a unique check like this
'member_id' => ['unique:member_record,foo']
If you would like to add additional where clauses then you would want to do something like this
'member_id' => ['unique:member_record,foo,NULL,id,bar,' . $uid]
This will return SQL looking like this
select count(*) as aggregate from member_record where foo = 660000000 and bar = 660000000

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');
}

updateOrCreate() gives Column not found: 1054 Unknown column '0' in 'where clause'

I'm trying to assign role to user when they attempt. But it gives me this error. I'm using updateOrCreate() because I want to use that method later to change user role
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'where
clause' (SQL: select * from roles where (0 = user_id and 1 = =
and 2 = 10) limit 1)
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger("user_id")->index();
$table->string("role_name");
$table->foreign("user_id")->references("id")->on("users")->onDelete("cascade");
});
RegisterController
protected function create(array $data)
{
$user = user::create([
'name' => $data['name'],
'email' => $data['email'],
"username" => $data["username"],
'password' => Hash::make($data['password']),
]);
if ($user) {
$model = new Role();
$model->assignNewbieRole($user->id);
}
return $user;
}
Role model
public function assignNewbieRole($id)
{
$this->updateOrCreate(["user_id","=",$id],["role_name","=","newbie"]);
}
How do I fix this ?
You need to pass an associated array instead of individual values:
$this->updateOrCreate(["user_id" => $id], ["role_name" => "newbie"]);
The values have to be set using a associative array where the column name is the key and the value is the value you want to find/insert.
$this->updateOrCreate(
["user_id" => $id],
["role_name" => "newbie"]
);

Categories