Kohana 3, исключение «неопределенный индекс» с добавлением данных m2m - PullRequest
1 голос
/ 07 мая 2010

Я опубликовал это на официальном форуме, но безрезультатно.

Я получаю Undefined index ошибку регистрации при попытке сохранить данные.

Моя базовая модель:

class Model_Enrollment extends ORM  {
               protected $_belongs_to = array('page' => array(), 'menugroup' => array());
          }

Model_Page

protected $_has_many = array('templates' => array(), 'menugroups' => array('through' => 'enrollment'));

Model_Menugroup

  protected $_has_many = array('menuitems' => array(), 'pages' => array('through' => 'enrollment'));
//Overriden save() method in Model_Menugroup:
public function save() {
    if (empty($this->created)) {
         $this->created = time();
    }
    parent::save();
    $this->reload();
    if (! $this->is_global) {
      if (! empty($this->groupOwnerPagesId) {
          $page = ORM::factory('page');
          foreach($this->groupOwnerPagesId as $id) {
            $this->add('enrollment', $page->find($id));
          }
       }
    }
}

Я сделал:

  • Я исправил имена таблиц в сводной модели, изменив их на единственные
  • Я даже сейчас использую одно и то же имя для сводной таблицы / модель = регистрация. Так же, как в учебнике. На всякий случай
  • Таким образом, сводная таблица имеет имя 'enrollment' и имеет 2 столбца: page_id, menugroup_id
  • Я пытался добавить pk в сводную таблицу, но ничего не изменилось
  • Я пытался добавить / удалить отношение БД между страницами / меню и сводной таблицей (InnoDB), но безуспешно
  • Я попытался сохранить все данные в контроллере, но с тем же плохим результатом :(

Я все еще получаю ту же ошибку:

Undefined index: enrollment in ORM line: $columns = array($this->_has_many[$alias]['foreign_key'], $this->_has_many[$alias]['far_key']);

Может кто-нибудь сказать мне, что может быть еще не так? У меня нет других идей: (* ​​1036 *

С уважением

Ответы [ 3 ]

0 голосов
/ 07 мая 2010

Зачисление в таблицу

CREATE TABLE IF NOT EXISTS `enrollments` (
  `page_id` int(11) NOT NULL,
  `menugroup_id` int(11) NOT NULL,
  KEY `page_id` (`page_id`,`menugroup_id`),
  KEY `menugroup_id` (`menugroup_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Таблица меню

CREATE TABLE IF NOT EXISTS `menugroups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `location` tinyint(4) NOT NULL,
  `is_global` tinyint(4) NOT NULL DEFAULT '1',
  `order` tinyint(4) NOT NULL,
  `created` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 

Столовые страницы

CREATE TABLE IF NOT EXISTS `pages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL,
  `link` varchar(100) NOT NULL,
  `keywords` tinytext,
  `description` tinytext,
  `template_id` int(11) unsigned DEFAULT NULL,
  `is_main` tinyint(4) NOT NULL DEFAULT '0',
  `header_on` tinyint(4) DEFAULT NULL,
  `footer_on` int(11) DEFAULT NULL,
  `sidebar_on` int(11) DEFAULT NULL,
  `content` longblob NOT NULL,
  `created` int(11) NOT NULL,
  `last_modified` int(11) DEFAULT NULL,
  `author` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `title` (`title`,`link`),
  UNIQUE KEY `link` (`link`),
  KEY `template_id` (`template_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8

Model_Enrollment

class Model_Enrollment extends ORM  {
    protected $_belongs_to = array('page' => array(), 'menugroup' => array());
}

Model_Page

класс Model_Page расширяет Model_FlyOrm {

protected $_filters = array(
                        'title' => array('trim' => NULL),
                        'content' => array('trim' => NULL),
                        'keywords' => array('trim' => NULL),
                        'description' => array('trim' => NULL)
                   );

protected $_has_many = array('templates' => array(), 'menugroups' => array('through' => 'enrollment', 'foreign_key' => 'page_id', 'far_key' => 'menugroup_id'));

protected $_rules = array(

           'title' => array(
               'not_empty' => array(),
               'min_length' => array(3),
               'max_length' => array(100),

           ),
           'keywords' => array(
               'max_length' => array(255),
           ),
           'description' => array(
               'max_length' => array(255),
           ),
           'template_id' => array(
               'digit' => array(),
           ),
           'header_on' => array(
               'digit' => array(),
           ),
           'footer_on' => array(
               'digit' => array(),
           ),
           'sidebar_on' => array(
               'digit' => array(),
           ),
           'is_main' => array(
               'digit' => array(),
           ),
           'content' => array(
               'not_empty' => array(),
               'min_length' => array(10),
           ),
           'created' => array(
               'digit' => array(),
           ),
           'last_modified' => array(
               'digit' => array(),
           ),
           'author' => array(
               'max_length' => array(50),
           )
);

protected $_callbacks = array(
    'title' => array('is_unique'),
    'link' => array('is_unique'),
);

private $result = array('msg' => '', 'is_success' => NULL);

public function __construct($id = null) {
    parent::__construct('pages', $id);
}

public function get_pages() {
    return $this->order_by('is_main', 'DESC')->find_all();
}

public function save() {
    $this->create_link();
    if (! $this->_loaded) {
        $this->created = time();
    } else {
        $this->last_modified = time();
    }
    if ($this->is_main) {
        $old_main = $this->get_main_page();
        if ($old_main->_loaded) {
            $old_main->is_main = 0;
            $old_main->save();
        }
    }
    return parent::save();
}

public function values($values) {
    foreach($values as $key => $val) {
        if ($val == self::NOT_SET)
            $values[$key] = NULL;
    }
    return parent::values($values);
}

public function _delete($id) {
    $this->set_result($this->get_msg('pages.success.delete'));
    if (is_array($id)) {
            $pages = ORM::factory('page')->where('id', 'IN', $id)->find_all();
            foreach ($pages as $page) {
              if ($page->is_main) {
                    $this->set_result($this->get_msg('pages.fail.main_page'), FALSE);
              } else {
                  $page->delete();
              }
            }
    } else {
        $this->find($id);
        if ($this->_loaded) {
            if ($this->is_main) {
                $this->set_result($this->get_msg('pages.fail.main_page'), FALSE);
            } else {
                $this->delete();
            }
        } else {
            $this->set_result($this->get_msg('pages.fail.delete'), FALSE);
        }
    }
}

public function get_result() {
    return $this->result;
}

public function __get($name) {
    $value = parent::__get($name);
    if ($name == 'created' || $name == 'last_modified')
        return date("Y-m-d H:i:s", $value);
    else return $value;
}

public function get_main_page() {
    return ORM::factory('page')->where('is_main', '=', 1)->find();
}

private function create_link() {
    $link = text::pl2en($this->title);
    $link = trim(preg_replace('/[^A-Za-z0-9\-\s]+/', '', $link));
    $link = preg_replace('/\s+/', '-', $link);
    $link = preg_replace('/^(-*)|(-*$)/', '', $link);
    $this->link = strtolower($link);
}

private function set_result($msg, $is_success = TRUE) {
    $this->result['msg'] = $msg;
    $this->result['is_success'] = $is_success;
}

private function get_msg($path) {
    return Kohana::message('messages', $path);
}

private function set_global_settings_if_required($global) {
    if (empty($this->template)) {
            $this->template = $global->template;
    }
    if (is_null($this->header_on)) {
            $this->header_on = $global->header_on;
    }
    if (is_null($this->sidebar_on)) {
            $this->sidebar_on = $global->sidebar_on;
    }
    if (is_null($this->footer_on)) {
            $this->footer_on = $global->footer_on;
    }
    if (empty($this->keywords)) {
            $this->keywords = $global->keywords;
    }
    if (empty($this->description)) {
            $this->description = $global->description;
    }
    if (empty($this->author)) {
            $this->author = $global->author;
    }
}
CONST NOT_SET = -1;

}

Model_Menugroup

class Model_MenuGroup extends Model_FlyOrm {

    protected $_has_many = array('menuitems' => array(), 'pages' => array('through' => 'enrollment', 'foreign_key' => 'menugroup_id', 'far_key' => 'page_id'));

    protected $_filters = array(
        'name' => array('trim' => NULL),
    );
    protected $_rules = array(
        'name' => array(
            'not_empty' => array(),
            'min_length' => array(2),
            'max_length' => array(100)
        ),
        'location' => array(
            'range' => array(0,2),
        ),
        'is_global' => array(
            'range' => array(0,1),
        ),
        'order' => array(
            'digit' => NULL,
        )
    );

    protected $_callbacks = array(
        'name' => array('is_unique'),
    );

    private $groupOwnerPagesId = array();

    public function __construct($id = NULL) {
        parent::__construct('menugroup', $id);
    }

    public function save() {
        if (empty($this->created)) {
             $this->created = time();
        }
        parent::save();
        $this->reload();
        if (! $this->is_global) {
            if (! empty($this->groupOwnerPagesId)) {
                $page = ORM::factory('page');
                foreach($this->groupOwnerPagesId as $id) {
                    $this->add('enrollment', $page->find($id));
                }
            }
        }
    }

    public function values($data) {
        parent::values($data);
        if (! isset($data['is_global'])) {
           if (isset($data['pages'])) {
               foreach( $data['pages'] as $key => $value) {
                   $this->groupOwnerPagesId[] = $key;
               }
           }
           $this->is_global = 0;
        }

    }

    public function check() {
        $result = parent::check();
        if (! $this->is_global) {
            if (empty($this->groupOwnerPagesId)) {
                $this->_validate->error('is_global', 'no_pages');
                return false;
            }
        }
        return $result;
    }

    public function __get($name) {
        $value = parent::__get($name);
        if ($name == 'created')
            return date("Y-m-d H:i:s", $value);
        else return $value;
    }

    public function get_by_location($id) {
        return $this->where('location', '=', $id)->order_by('order', 'ASC')->find_all();
    }

    public function get_all_groups() {
        return $this->find_all();
    }

    public function get_parent_pages_if_exists() {
        if (! $this->is_global) {
            return $this->pages->find_all();
        } else {
            return FALSE;
        }
    }

    public function get_items($group_id) {
        return $this->find($group_id)->menuitems->find_all();
    }
}
?>

Я также заметил, что у меня есть одно имя столбца с зарезервированным словом mysql 'order', я изменил его на 'ord', но без положительного результата.

0 голосов
/ 07 мая 2010

Мой плохой!

Вместо:

            $this->add('pages', $page->find($id));

Я пытаюсь добавить пивот!

            $this->add('pages', $page->find($id));

Как я могу быть таким слепым!

В любом случае, большое спасибо Kemo за помощь и извините, что потратили ваше время на мою большую ошибку.

0 голосов
/ 07 мая 2010

Убедитесь, что таблицы названы таким образом;

Model_Page = table pages
Model_Enrollment = table enrollments
Model_Menugroup = table menugroups

Если это не помогает, попробуйте определить 'model', 'foreign_key' & 'far_key' в Model_Menugroup и Model_Page 'имеет много' определений, хотя есть правило, что «если вам нужно определить имя таблицы, внешние ключи или дальние ключи вручную, что-то пропущено в дизайне БД (фактически, если вам нужно определить что-то, что должно быть определено автоматически):)

Если вы все еще не поняли, в чем ошибка, опубликуйте здесь все 3 таблицы CREATE запросов и моделей.

EDIT:

проверил это, проблема в том, что вы передаете имя модели вместо имени таблицы для "сквозного". Попробуйте использовать «enrollments» вместо «enrollment»:)

...