Не удается заставить DataMapper работать в CodeIgniter

Я пытаюсь реализовать ORM в приложении CodeIgniter, но не могу заставить его работать. Для начала я просто пытаюсь создать простую тестовую модель:

<?php

class Cart extends DataMapper
{

    public function __construct()
    {
        // model constructor
        parent::__construct();
    }

    var $validation = array(
        'username' => array(
            'label' => 'UserName',
            'rules' => array('required', 'trim', 'unique', 'alpha_dash', 'min_length' => 1, 'max_length' => 50),
        )
    );
}

?>

И затем в контроллере я пробую это:

public function __construct()
{
    parent::__construct();
    $this->load->model('cart');
}

public function index()
{   

    $cart = new Cart();
}

Но я даже не могу пройти мимо конструктора. Отладчик останавливается и выдает мне сообщение «Ожидание входящего соединения с ключом ide xxxxx» (случайное число)

Кстати, имя файла класса модели тележки указано в нижнем регистре, а имя класса в верхнем регистре. Я пробовал оба в конструкторе.

Я внимательно следовал инструкциям по установке, скопировав два файла преобразователя данных в библиотеки и папки конфигурации, а также автоматически загрузив библиотеку преобразователя данных.

Но это просто не работает. Я что-то упускаю? Таблица, которую я пытаюсь сопоставить, представляет собой только тестовую таблицу, которая на самом деле имеет только поле идентификатора и имени пользователя. На самом деле я не понимаю массив проверки, а просто следовал примерам в документах и ​​модифицировал свое поле. Поле id не похоже на то, что кто-то вставил массив проверки.

Я также должен упомянуть, что я новичок в CodeIgniter.


person Anders    schedule 16.10.2011    source источник


Ответы (2)


Ваш код кажется в основном правильным для использования с DataMapper ORM и CodeIgniter.

Чтобы немного объяснить, DataMapper — это просто уровень абстракции. Он справляется со многими потребностями при работе с базами данных и сопоставлении ваших объектов с вашими таблицами. При этом вам не нужно загружать свои модели и т. Д. Пока вы автоматически загружаете свою библиотеку базы данных и библиотеку datamapper, вы можете использовать DataMapper.

Массив проверки позволяет DataMapper знать требования к вашим свойствам. Таким образом, если вы попытаетесь сохранить объект, а одно из свойств, которые вы создали/изменили, не соответствует этим требованиям, ваше сохранение завершится ошибкой, и вы получите сообщение об ошибке:

// For example
if ($myObj->save())
{
    // $myObj validation passed and is saved to db
}
else
{
    // $myObj validation failed, save did not complete
    echo $myObj->error->string;
}

В Codeigniter уже есть библиотека с именем Cart, поэтому вам не стоит называть свою модель Cart. Таким образом, вы можете переименовать эту модель в Basket или как-нибудь еще, что имеет смысл.

Я знаю, что вы все еще пытаетесь заставить все работать, но я чувствую, что вам нужно немного подумать о вашей структуре данных. Вы бы не сохранили username в объекте Cart, поэтому мы используем отношения. Итак, я бы структурировал это примерно так:

// baskets table (a table represents many baskets, therefore it is plural)
id
user_id
blah
blah
created
updated

// users table
id
username
email_address
created
updated

// basket model (a model represents 1 basket, therefore it is singular)
class Basket extends DataMapper
{
    public function __construct()
    {
        parent::__construct();
    }
    var $has_one = array('user'); // each basket belongs to one user
    var $validation = array(...);
}

// user model
class User extends DataMapper
{
    public function __construct()
    {
        parent::__construct();
    }
    var $has_many = array('basket'); // each user can have many baskets
    var $validation = array(...);
}

// controller
public function __construct()
{
     parent::__construct();
}

public function index()
{   
    $basket = new Basket();
    $basket->blah = 'whatever';
    $basket->save();
    // at this point, $basket is saved to the database
    // now let's add it to the user
    $user = new User();
    $user->where('id', 1)->get(1);
    // now we have a user
    // save the relationship to the basket
    $user->save($basket);
    // now $basket->user_id == 1

    // get the username from the basket
    $u = $basket->user->get();
    $username = $u->username;

    // yes, there are faster and shorter ways to write most of this,
    // but I think for beginners, this syntax is easier to understand
}
person swatkins    schedule 18.10.2011
comment
Много раз, когда у меня возникает проблема, которую я не могу отследить, это связано с тем, что я назвал модель или контроллер или что-то с повторяющимся именем. Не знаю, твоя ли это проблема, но ты можешь проверить это. - person swatkins; 18.10.2011
comment
Я до сих пор не знаю, действительно ли ваш ответ отвечает на вопрос, но вы можете быть правы, возможно, есть какой-то конфликт имен. В любом случае, это был лучший ответ, так что это ваша заслуга. Я нашел эту ссылку с образцом приложения, которое работает, поэтому я все равно использовал его в качестве отправной точки. Этому парню тоже спасибо :-) terrymatula.com /разработка/2011/ - person Anders; 26.10.2011
comment
Вы пытались удалить $this->load->model('cart'); из конструктора? Как я уже сказал в своем ответе, datamapper загружает для вас модели. Это может вызвать конфликт. - person swatkins; 26.10.2011

В документации CodeIgniter о моделях говорится, что вы можете загрузить модель, вызвав

$this->load->model('Model_name');

в конструкторе, и что вы можете получить доступ к этой модели в своем контроллере, выполнив

$this->Model_name->function();

Поэтому вы должны изменить свой код контроллера на

public function __construct()
{
    parent::__construct();
    $this->load->model('Cart');
}

public function index()
{   

    $this->Cart->functionCall();
}
person Jan-Henk    schedule 17.10.2011
comment
Нет, к сожалению, это все еще не работает. Вы уверены, что это относится к использованию с DataMapper, потому что в его документации говорится, что это отменяет обычное использование моделей в CI... И все примеры использования показывают, что у меня есть в моем примере кода. Я нашел загружаемый пример проекта, который отлично работает, я просто не знаю, в чем разница с моим проектом. За исключением того, что я также использую Ion Auth для аутентификации, так что, возможно, здесь есть какой-то конфликт ...? - person Anders; 18.10.2011
comment
Тогда я не знаю, я не очень знаком с CodeIgniter. У меня была последняя идея: вы пытались удалить оператор var $validation = array(...)? - person Jan-Henk; 18.10.2011
comment
@AndersSvensson использует ORM поверх активной записи CI, поэтому загружать модели не нужно. - person swatkins; 18.10.2011