проблемы с проверкой отношений codeigniter datamapper

Мне нужно настроить правила проверки для проверки связанных элементов на конкретном объекте, то есть: пользователь может иметь не более 3 продуктов, связанных с ним.

Я считаю, что DataMapper может проверить эту проверку с помощью правила _related_max_size, но я не могу понять, как использовать его в массиве $validation в модели.

До сих пор я пробовал это как в своих моделях пользователя, так и в моделях продукта:

var $validation = array(
    'product' => array(
         'rules' => array('max_size' => 3)
    )
);

Может ли кто-нибудь показать мне пример того, как настроить это на модели, контроллере и, наконец, на представлении?

Изменить: я имею в виду, что у пользователя есть много продуктов, и он может создать определенное их количество, скажем, 3 продукта, когда эта сумма будет достигнута, пользователь больше не сможет создавать продукты, и это правило проверки не должно разрешать пользователю для создания большего количества продуктов.

Это будет схема БД:

Users table
------------------
id   |  username  |
------------------

Products table
------------------------
id  | user_id |  name   |
------------------------

Подробнее здесь: http://codeigniter.com/forums/viewthread/178045/P500/

Спасибо!

ИЗМЕНИТЬ:

Хорошо, теперь у меня все работает… За исключением того, что мне нужно сделать следующее:

var $validation = array(
    'product' => array(
        'label' => 'productos',
        'rules' => array('required','max_size' => $products_limit)
    )
); 

$products_limit исходит из «плана», связанного с пользователем, и сохраняется в сеансе, когда пользователь входит в систему. Когда я пытаюсь запустить это, я получаю:

Parse error: syntax error, unexpected T_VARIABLE in /var/www/stocker/application/models/user.php on line 11 

Есть ли способ сделать этот параметр динамическим?


person ricardocasares    schedule 14.02.2012    source источник
comment
не могли бы вы объяснить это немного больше, что именно вы хотите? пример того, что выберет пользователь и что вы пытаетесь проверить?   -  person Shabib    schedule 14.02.2012


Ответы (3)


В модели

var $validation = array(
    array(
        'field' => 'username',
        'label' => 'Username',
        'rules' => array('required')
    )
);

В контроллере. $this -> $object = new Your_model();

$object->validate();

    if ($object->valid)
    { $object->save();

        // Validation Passed
    }
    else
    { $data['error'] = $object->error;
        // Validation Failed
    }

С учетом.

echo $error->field_name
person Didozavar    schedule 23.02.2012
comment
Спасибо @Didozavar, но я пытаюсь проверить отношения, поэтому в моей пользовательской модели, например, у меня есть var $validation = array('product' => 'rules' => array('max_size' => 3)); И дело в том, что мне нужно проверить, сколько продуктов создал пользователь, прежде чем он сможет вставить другой продукт на БД. Короче говоря, то, что я думаю, не работает, так это то, как я сохраняю или подтверждаю отношения. - person ricardocasares; 24.02.2012
comment
Прямо сейчас я получаю эту ошибку: Error Number: 1054 Unknown column 'products.product_id' in 'where clause' SELECT COUNT(*) AS numrows` ОТ (products) ГДЕ products.user_id = 1 И products.product_id НЕ В (307) Имя файла: /var/www/stocker/libraries/datamapper.php Номер строки: 2596` пока пытаюсь сделать это: $u = new User(); $p = new Product(); $p->name = "PEPE"; $p->existence = 2; $p->threshold = 1; $p->measure_id = 3; $p->save(); $u->where('username','rcasares')->get(); echo $u->save($p); - person ricardocasares; 24.02.2012
comment
Продукт сохраняется, и echo $u->save($p); возвращает TRUE, когда на самом деле у этого пользователя более 3 продуктов. - person ricardocasares; 24.02.2012

Я никогда раньше не использовал Codeigniter, но дайте мне шанс помочь вам. Пока я не нашел встроенной проверки в Code-igniter (поправьте меня, если я ошибаюсь).

Один обходной путь, который я мог придумать, — это Обратный вызов: ваши собственные функции проверки. Ниже фрагмент. Извините меня, если это не сработало, как вы хотите.

В модели: (создайте что-то вроде)

function product_limit($id)
{
    $this->db->where('product_id',$id);
    $query = $this->db->get('products');
    if ($query->num_rows() > 3){
        return true;
    }
    else{
        return false;
    }
}

В контроллере: (создайте что-то вроде)

function productkey_limit($id)
{
    $this->product_model->product_exists($id);
}

public function index()
{
    $this->form_validation->set_rules('username', 'Username', 'callback_product_limit');
}

Для получения дополнительной информации пожалуйста, обратитесь к странице руководства, которая дает более полную информацию. Я также новичок в CodeIgniter. Но я надеюсь, что это поможет вам, а не усложнит вас.

person Yeo    schedule 19.02.2012

Сначала настройте пользовательское правило проверки в libraries/MY_Form_validation.php.

Если файл не существует, создайте его.

Содержание MY_Form_validation.php:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation
{
    function __construct($config = array())
    {   
        parent::__construct($config);
    }

    function valid_num_products()
    {
       //Perhaps it would be better to store a maxProducts column in your users table. That way, every user can have a different max products? (just a thought). For now, let's be static.
       $maxProducts = 3;

       //The $this object is not available in libraries, you must request an instance of CI then, $this will be known as $CI...Yes the ampersand is correct, you want it by reference because it's huge.
       $CI =& get_instance();

       //Assumptions: You have stored logged in user details in the global data array & You have installed DataMapper + Set up your Product and User models.
       $p = new Product();
       $count = $p->where('user_id', $CI->data['user']['id'])->count();
       if($count>=$maxProducts) return false;
       else return true;
    }
}

Затем настройте правило в config/form_validation.php.

Содержимое form_validation.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config = array
(   
    'addProduct' => array
    (
        array
        (
                'field' => 'name',
                'label' => 'Product Name',
                'rules' => 'required|valid_num_products'
        )
    )
);

Затем настройте сообщение об ошибке в language/english/form_validation_lang.php. Добавьте следующую строку:

$lang['valid_num_products'] = "Sorry, you have exceeded your maximum number of allowable products.";

Теперь в контроллере вам понадобится что-то вроде:

class Products extends MY_In_Controller
{
    function __construct()
    {
        parent::__construct();
        $this->load->library('form_validation');
    }

    function add()
    {
        $p = $this->input->post();
        //was there even a post to the server?
        if($p){
            //yes there was a post to the server. run form validation.
            if($this->form_validation->run('addProduct')){
                //it's safe to add. grab the user, create the product and save the relationship.
                $u = new User($this->data['user']['id']);
                $x = new Product();
                $x->name = $p['name'];
                $x->save($u);
            }
            else{
                //there was an error. should print the error message we wrote above.
                echo validation_errors();
            }
        }
    }
}

Наконец, вы можете задаться вопросом, почему я унаследовал от MY_In_Controller. В своем блоге Фил Стерджен написал отличную статью под названием Держите его сухим. В посте он объясняет, как писать контроллеры, которые наследуются от контроллеров, контролирующих доступ. Используя эту парадигму, можно предположить, что контроллеры, унаследованные от MY_In_Controller, вошли в систему, и, следовательно, предполагается, что материалы $this->data['user']['id'] доступны. На самом деле $this->data['user']['id'] установлен в MY_In_Controller. Это поможет вам разделить вашу логику таким образом, чтобы вы не проверяли статус входа в систему в конструкторах ваших контроллеров или (что еще хуже) в их функциях.

person Jordan Arseno    schedule 21.02.2012