CodeIgniter Forums

Full Version: Permissions validation in model? (object belongs to user)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

This is my first post here, so please be gently for me and excuse me my english Smile

I was reading today about keeping controllers slim and moving validation rules to models but I don't know if I get it right. For simplicity, we have 2 models: users and posts.
Users can edit their posts, however each edit consumes a point. What do you think is the most natural way of validating this and why?

For me the most natural way would be:

In controller I can check if a post exists and belongs to user, if it doesn't just display a main page (no need for any fancy logic here since this situation shouldn't really happen). Here I can also check if user has enough points before even loading a model.
In model I can have form_validation rules for a post content/title and any other property.
That way If I introduce for example a control panel where as an admin I can edit every post, I can use that code and won't have to deal with "belongs to user/has enough points" rules (which wouldn't be applicable to admin account).
On the other hand, I could pass to edit method additional parameters and based on them have additional rules - that way I would keep everything inside Model.

What do you think is the right approach and why?

Thank you for any answers!
@qmd,

Welcome to the CI community.

I pretty much follow the path outlined in the CI documentation ( https://codeigniter.com/user_guide/tutor...l#tutorial ) with some slight differences when it comes to MVC development but that is the beauty of CI. You have flexibility. If you want to see real examples look at the github link for the website ( https://github.com/bcit-ci/codeigniter-website ) or check out Lonnie's code ( https://github.com/lonnieezell ) - Lead Developer for CI4.
IMO...

Model should only validate data when needed. Meaning, create, edit, delete, restore. Controller should validate, in a basic way, data the *view form* needs. Seems like a small difference, but it's major when you get into the actual application of it.

For example, allow the controller to use the built in form_validation() routine for catching user input issues before you involve a model. If those simple validation rules are met, then you have your model validate the form data against actual/strict expected values.

If you're building a 'Create Support Ticket' form, controller would validate that the title/subject isn't empty and is of some length, that they provided a description, and that they selected a priority. The model would validate that the selected priority is one of those listed in Support_ticket:TongueRIORITY_URGENT, Support_ticket:TongueRIORITY_NORMAL, Support_ticket:TongueRIORITY_LOW. Creating these model constants allows you to use them system wide and not have the actual text values scattered throughout your code base.

I'm aware the built-in validator allows for "in_list[]", but - that's not reusable, and hardly maintainable. It's best to validate those values in a subroutine within your Support_ticket::create() method.

Another use of the constants would be creating a model method like...

PHP Code:
Class Support_ticket extends MY_Model {
    const 
PRIORITY_HIGH 'high';
    const 
PRIORITY_NORMAL 'normal';
    const 
PRIORITY_LOW 'low';

    public function 
__construct($id=NULL) {
        
parent::__construct();
        
$this->loadById($id);
    }

    public function 
create($data_set=[]) {
        if(
TRUE === $this->is_loaded) {
            return 
'Model is already loaded';
        }

        if(
TRUE !== ($validation_result $this->validateDataSet($data_set))) {
            return 
$validation_result;
        }

        
// Create the record

        
return TRUE;
    }

    public function 
isHighPriority() {
        return 
TRUE === $this->is_loaded && static::PRIORITY_HIGH === $this->properties['priority'];
    }

    public function 
validateDataSet($data_set=[]) {
        if(!
is_array($data_set) || empty($data_set)) {
            return 
'Invalid $data_set';
        }

        if(
array_key_exists('priority'$data_set)) {
            if(!
in_array($data_set['priority'], [static::PRIORITY_HIGH, static::PRIORITY_NORMAL, static::PRIORITY_LOW])) {
                return 
'Invalid priority selection';
            }
        }

        return 
TRUE;
    }