Showing posts with label Laravel. Show all posts
Showing posts with label Laravel. Show all posts

Monday, July 2, 2018

Putting validation rules at your models

Validation is one of the vital part of saving data coming from user. For instance you want to accept an email format but the user didn't supply the right data, that would be a disaster in a way, right?

Laravel's validation features has been there since the beginning but might as well use it. Basic usage of validation are as follows.

Include the Validator into your controller, in my case I like to use the following code snippet. 

$validator = Validator::make($request->all(),  [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]
);

          if ($validator->fails()) {
                    return response()->json([
                        'result' => $validator->messages(),
                        'message' => "Encountered validation error."
                    ], 400);

                  // redirect can also be put here.
            }

//code here if validation didn't fail


Code above starts by creating custom validation as stated from Laravel manual then checks if the validation failed. The creation of validation part can be repetitive in some cases and adding more conditions can be tricky since you have to look where controller did you use the rules.

I think it was from CakePHP that validation rules are put inside models so I applied similar thing.

In my models, I would put the following sample rules,

   protected static $rules = [
'title' => 'required|unique:posts|max:255',
'body' => 'required'
    ];

and a static function that basically returns the rules.

    public static function getRules() {
        return static::$rules;
    }

The in my controller's function, I would simply use

 $validator = Validator::make($input, Post::getRules());
Now, I can access or use my validation anywhere and update my rules in just one place which is the model.

In some cases, updating record is different from your create/new record rules so you can also put  the following function to your model

    public function getUpdateRules() {
        $updateRules = [];
        foreach(self::getRules() as $field => $rule) {
            $newRule = [];
            $ruleParts = explode('|',$rule);
            foreach($ruleParts as $part) {
                if(strpos($part,'unique:') === 0) {
                    if ( ! $this->isDirty($field)) {
                        $part = $part . ',' . $field . ',' . $this->getAttribute($field) . ',' . $field;
                    }
                }
                $newRule[] = $part;
            }
            $updateRules[$field] = join('|', $newRule);
        }
        return $updateRules;
    }

Credits: Found the code getUpdateRules function at StackOverflow.

That's it for now.



Thursday, September 21, 2017

jQuery ajax post not working in Laravel 5.3

Here's the issue jQuery ajax post not working in Laravel 5.3 (could be occurring to other version too).

So here's the details, I created a jQuery ajax post to our Laravel backend. You might ask, why not just VueJS or other JS framework? Well, basically just a simple ajax request so why bother.

For a developer like me who immediately get his feet wet without reading in development, I would keep on trying until it'll work.

My jQuery code goes below:

      var request = $.post("/api/requestkoto",{
                data: {
                    'fieldOne': fieldOne,
                    'fieldTwo': fieldTwo,
                }
            });

For web developers, browser's developer console is their friend. It was pain in the ass to see that your request is not working. From the console the POST is turning to GET. I started to wonder and feeling lost. Where and Why it's happening?

 Tried using jQuery or $.

I also I tried disabling Larave's security by commenting out \App\Http\Middleware\VerifyCsrfToken::class, at HTTP/Kernel wherein my post started to work. Of course, it wasn't the solution.

Well, it turns out it's Laravel's security feature which states and can be found here.

In addition to checking for the CSRF token as a POST parameter, the VerifyCsrfToken middleware will also check for the X-CSRF-TOKEN request header. You could, for example, store the token in a HTML meta tag:

<meta name="csrf-token" content="{{ csrf_token() }}">
And you have to add this your code too.

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});
So with that, I my new ajax POST request would be

      var request = $.post("/api/requestkoto",{
                data: {
                     '_token': window.Laravel.csrfToken, 'fieldOne': fieldOne,
                    'fieldTwo': fieldTwo,
                }
            });
I just added  '_token': window.Laravel.csrfToken to the request and everything works as expected. Spent more than 1 hour tracing from backend to javascript.

Okay. That's it for now.