I don't understand why this doesn't work, i have searched the forums and read the official documentation, obviously I'm making a silly mistake:
public function rules()
{
$customer = Customer::find($this->customers);
return [
'data.name' => 'required|unique:customers,name,1'
];
}
That is a CustomerUpdateFormRequest that i created, i manually typed the customer id which is 1 in the rule, also with: 'data.name' => 'required|unique:customers,name,'.$customer->id,
The problem is that it still doesnt pass the unique validation, i giving me the Customer already exists error even after manually or dynamically type the customer id.
I read this http://laravel.com/docs/5.0/validation and https://laracasts.com/discuss/channels/requests/laravel-5-validation-request-how-to-handle-validation-on-update and I 'Believe' that my code is correct, why is not working?
The code above is working just fine, no syntax errors or logic, the problem was in the database, there was another customer with the same data inserted i guess before the validation form was created.
I dont know if i should delete this question or leave it here, anyway the code its fine if u have any problems like mine PLEASE CHECK YOUR DB.
Thanks!
public function rules()
{
$customer= $this->route('customer'); //$this->('route-name')
return [
'data.name' => 'required|unique:customers,name,' . $customer->id
];
}
Related
I have inherited a CakePHP 3 project handling some readings at certain dates. We have an API connected to a phone app that takes the well readings and inserts them to the database.
The readings as well as created by and updated by timestamps work correctly, but in this inherited project they have a separate date column 'reading_date' that is giving me 0015-10-05. The other aspects of the API controller work fine, but this continues to give me issues. I have the code for the add() method below
/**
* Add method
*
* #return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
*/
public function add()
{
$wellReading = $this->WellReadings->newEntity();
if ($this->request->is('post')) {
$data = $this->request->getData();
$this->log($this->request->getAttribute('params'));
$this->ats_log($this->request->getAttribute('params'));
$data['reading_date'] = date('Y-m-d', strtotime('Today'));
$data['reading_time'] = date('G:i:s');
$wellReading = $this->WellReadings->newEntity($wellReading, $data);
if ($this->WellReadings->save($wellReading)) {
// we're going to add some related info in here so we can return it with the inserted record in the API
$operator = $this->WellReadings->Operators->findById($wellReading->operator_id)->first();
$well = $this->WellReadings->Wells->findById($wellReading->well_id)->first();
$wellReading->reading_date = date('Y-m-d');
$wellReading->operator = $operator->name;
$wellReading->well = $well->identifier;
$wellReading->region_id = $well->region_id;
$this->set(['success' => true, 'data' => $wellReading, '_serialize' => ['success', 'data']]);
} else {
$this->set(['success' => false, 'errors' => $wellReading->errors(), '_serialize' => ['success', 'errors']]);
}
}
}
I have removed the UseLocaleParser from bootstrap.php as I have read that his causes issues in older CakePHP versions.
Also, $this->log() does not give me anything, no matter what I try. I have tried to use the data variable, and many different iterations of $this->request->, Params, Attribute, getData, nothing will show up in my error logs.
The ats_log method should take $data and write whatever is in that variable to a separate log file, we had this idea when nothing showed up in the Cake log function, but everything in that file is NULL. Still, the readings show up in the DB, and only the reading_date column is wrong.
Any help is greatly appreciated.
EDIT: I have been informed by my lead dev we have to keep the LocaleParser on.
So, this code did not show the whole picture after working into the project more.
My senior dev had already changed previous code from
$data['reading_date'] = date('d/m/Y', strtotime('Today'));
to what I have above. This caused the validator on the WellReadingsTable to throw an error. In the validator, the accepted format was 'mdY'. I am not sure why someone would allow invalid date format into the DB but after switching it to 'Ymd' data is being entered correctly.
Second part, instead of using $this->log(); to capture data, I was able to use debug(); to get data to show up in a separate log in the filestructure.
I'm validating question and answers (for test creation). I'd like to ensure that the answers array contains at least one 'correct' item. So where answers.*.correct => true.
I currently have the following:
public function rules()
{
return [
'title' => 'required|string|max:255',
'test_id' => 'required|integer|exists:tests,id',
'content' => 'required',
'answers' => 'required|array',
'answers.*.text' => 'required|string|max:255',
'answers.*.correct' => 'required|boolean'
];
}
At the moment i can miss out adding a correct answer causing an impossible question.
I've checked the documentation and can't see anything that stands out.
Any help would be appreciated.
EDIT ANSWER
I used this (as the answer mentions): Laravel validate at least one item in a form array
I managed to create a custom rule like so:
public function passes($attribute, $value)
{
foreach ($value as $arrayElement) {
if ($arrayElement['correct'] == true) {
return true;
}
}
return false;
}
Then in my existing rules() section for the request I added in the new rule i created:
'answers' => ['required', 'array', new ArrayAtLeastOneBoolTrue()],
You are here validating that the array answers has:
A string with max. 255 chars (text)
A boolean (correct)
To check the completeness of this array, the Laravel request is the wrong place to check. Technically it would be possible to create your own validation rule, but makes no sense here. Instead you should iterate this array in your controller and verify the completeness of each answers.
Two more ideas, to do it better:
Don't send all answers and if they were answered correctly in one single array. Instead, send the selected answer to your api with a single request per answer at the moment the user clicks it. This will 1. prevent that somebody can send you the information that he answered 100% correct (not good if this is a school software :) ) and 2. depending on how much questions there are it will reduce the data sent to the server to a minumum, mainly because...
... it seems you send the whole text of the question to the server to identify the answer. Use a unique ID per question and send it as question ID + the selected or entered answer.
EDIT: Thanks for the comments, sorry for my misunderstanding here. As mentioned above then of course custom validation makes totally sense here to check per question if at least one answer is correct. Check this out: https://stackoverflow.com/a/53791208/2264877
I'm trying to figure out how to properly code the update() function in eloquent to return either 0 or 1 based on user input in a form. For example, if I hit the update button without making any changes, it returns 1. Shouldn't it return 0?
I tried researching for solutions like here in stackoverflow to see if anyone has the same problem as I am facing. But so far not luck. I also tried modifying the code, but no luck.
public function update(Request $request, $id)
{
$UCPost = UCPost::find($id);
$UCPost->gown_2019 = $request->input('Gown2019');
$UCPost->gown_2017_2018 = $request->input('Gown20172018');
$UCPost->gown_2016 = $request->input('Gown2016');
$UCPost->gown_2015 = $request->input('Gown2015');
$UCPost->Light_Blue = $request->input('LightBlue');
$UCPost->Seconds = $request->input('Seconds');
$UCPost->Velveteen = $request->input('Velveteen');
$UCPost->Velveteen_discolored = $request->input('Velveteen_discolored');
$UCPost->Rental = $request->input('Rental');
$UCPost->Rentals_Out = $request->input('Rentals_Out');
$UCPost->Rentals_Left = $request->input('Rentals_Left');
return $UCPost->where('id', $id)->update(
[
'gown_2019' => $UCPost->gown_2019,
'gown_2017_2018' => $UCPost->gown_2017_2018,
'gown_2016' => $UCPost->gown_2016,
'gown_2015' => $UCPost->gown_2015,
'Light_Blue' => $UCPost->Light_Blue,
'Seconds' => $UCPost->Seconds,
'Velveteen' => $UCPost->Velveteen,
'Velveteen_discolored' => $UCPost->Velveteen_discolored,
'Rental' => $UCPost->Rental ,
'Rentals_Out' => $UCPost->Rentals_Out,
'Rentals_Left' => $UCPost->Rentals_Left
]
);
}
The code above as I mentioned earlier, it always returns 1 regardless of any changes made to the form. I want it to return 0 if there are no changes by the user or if they accidentally hit the update button. I'm trying to find the equivalent of mysqli_affected_rows in Eloquent.
You are calling the update() method on your model. This will return 1 if the update was successful. It doesn't matter if there were any changes made, always 1 on successful update.
If you would like to only save to the database if there are changes, you can use the save() method instead, which checks to see if changes are present, and only writes to the database if the data is different. You have already created code to do this, by setting the model to have all of the new data from the sheet, so a simple save() at the end (with a check to see if it saves), will do what you want.
However, your current code is doing a lot of extra work. You are assigning all the variables to the model, and then updating based on that assignment of data to the model. You don't have to do all that assignment again in the update method. Once you have set the fields, you can save immediately, you don't have to re-assign all the variables. So:
$UCPost->gown_2019 = $request->input('Gown2019');
// etc..
$UCPost->Rentals_Left = $request->input('Rentals_Left');
$UCPost->save();
Will get you where you want to go and will only save if different.
If you have control over your form, and can change the form element names to match your database, this can be even easier. You can do all of this in one line:
$UCPost->update($request->all());
If you want to check if the model is dirty just call isDirty():
if($UCPost->isDirty()){
// changes have been made
}
Finally, if you want to verify if anything was changed after either method (save or update):
if ($UCPost->wasChanged()) {
// changes have been made
}
Hope this helps
This is my first Laravel project, i'm making a routing mistake and have been trying to solve it for days now, solution must be very simple, so i'm missing something. I attempted some similar solutions I found in other posts here, but they contained much more complex code and only made things worse for me at this point.
I have a GET route like:
Route::get('peppers/{id}', function ($id) {
//return $id;
$pepper = DB::table('peppers')->get();
return view('peppers',['id' => $id,'pepper'=>$pepper]);
})->name('peppers');
And I also have a simple POST route. (for a form that I used on another page)
It inserts everything correctly into my database. The problems is in the redirect.
Route::post('pepperCreate', function (\Illuminate\Http\Request $request) {
$post = $_POST;
$pepperType = $_POST["pepperType"];
$pepperURL = $_POST["pepperURL"];
$pepperAuthor = $_POST["pepperAuthor"];
and so on... ending with:
return redirect()->route('peppers/{id}', [$id]);
})->name('pepperCreate');
But every time i try to redirect, it gives me an error saying:
Route [peppers/{id}] not defined.
(My question is: Did i not just define that GET route, because it works when I click into that URL) with:
{{$topic->topicTitle}}
After days of trying different variations of this, i'm trying to figure out what i'm missing here. Any input is appreciated.
Indeed, because you need to use your route's name, and use an associative array for the parameters too, as in:
return redirect()->route('peppers', ['id' => $id]);
Hope this helps!
I am trying to setup a simple Restfull api using cakephp.
I followed the documentation from the Cakephp site.
But I am encountering the following issue.
I am using Postman plugin to test the Api calls.
I have a table called 'Categories' and in its controller have an action add().
public function add() {
if ($this->request->is('post')) {
$this->Category->create();
if ($this->Category->save($this->data)) {
$message = 'Saved';
}
else {
$message = 'Error';
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
}
and in db, I have Category table with schema (id (int 11, PK, A_I), name(varchar(40)), created (datetime), modified(datetime)).
So from postman I send POST requests to http://myProject/categories.json.
From my understanding when i send key:name and value: test, it must save into the database, which works fine. But I must get error when I replace the "key" with something other than name. i.e for exmaple key: name123 and value: test2, But this data too is getting saved in the db without any error except for the name field. i.e it is saving (id:some value, name:"", created:somevalue, modified:someValue)
I dont understand how. Any help will be greatly appreciated.
You will need to provide more info because what you say doesn't make sense. For example what do your posted data look like? Is there any kind of validation in the model? How do you expect a key/value pair to be stored in only one field (specifically name) in the DB?
What happens now is that you tell Cake to save the supplied data ($this->Category->save($this->data)) although you don't check (via cake's validation rules in the model or any other means) that it contains useful arguments and especially Category.name.
As computers will just do what you tell them to do and not what you imply or have in mind, it goes on and sends the calculated created/modified fields to the DB which in turn saves them with the autoincremented ID. Since name doesn't have a UNIQUE or NOT NULL field condition in the DB it is saved as NULL or empty string.