public function validate($attributes=[], $returnData=false)
    {
        // Data fetched by ORM or input
        $data = ($attributes) ? $attributes : $this->_writeProperties;
        // Filter first
        $data = $this->filter($data);
        // ORM re-assign properties
        $this->_writeProperties = (!$attributes) ? $data : $this->_writeProperties;
        // Get validation rules from function setting
        $rules = $this->rules();

        // The ORM update will only collect rules with corresponding modified attributes.
        if ($this->_selfCondition) {

            $newRules = [];
            foreach ((array) $rules as $key => $rule) {
                if (isset($this->_writeProperties[$rule['field']])) {
                    // Add into new rules for updating
                    $newRules[] = $rule;
                }
            }
            // Replace with mapping rules
            $rules = $newRules;
        }

        // Check if has rules
        if (empty($rules))
            return ($returnData) ? $data : true;

        // CodeIgniter form_validation doesn't work with empty array data
        if (empty($data))
            return false;

        // Load CodeIgniter form_validation library for yidas/model namespace, which has no effect on common one
        get_instance()->load->library('form_validation', null, 'yidas_model_form_validation');
        // Get CodeIgniter validator
        $validator = get_instance()->yidas_model_form_validation;
        $validator->reset_validation();
        $validator->set_data($data);
        $validator->set_rules($rules);
        // Run Validate
        $result = $validator->run();
        
        // Result handle
        if ($result===false) {

            $this->_errors = $validator->error_array();
            return false;

        } else {

            return ($returnData) ? $data : true;
        }
    }