CodeIgniter ActiveRecord проблемы - PullRequest
       5

CodeIgniter ActiveRecord проблемы

0 голосов
/ 26 сентября 2010

Я пытаюсь построить свое первое приложение на CodeIgniter.Я также впервые пытаюсь придерживаться ООП и MVC как можно больше.Пока все идет хорошо, но теперь, когда я пытаюсь написать свою первую модель, у меня возникли некоторые проблемы.Вот ошибка, которую я получаю:

Произошла ошибка базы данных

Номер ошибки: 1064

У вас ошибка в синтаксисе SQL;проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы найти правильный синтаксис для использования рядом с 'Castledine' в строке 3

SELECT * FROM (authors) WHERE author = Earle Castledine

Что, как вы увидите ниже, относится к следующей строке в моей модели:

$this->db->get_where('authors', array('author' => $author));

Я не совсем уверен, почему выдает ошибку.Это потому, что Эрл Каследин не в кавычках?Если так, почему CI не помещает их туда?Я сомневаюсь, что это проблема, скорее, чтобы думать, что это моя вина, но я не уверен.

У меня также есть другая проблема.Ни теги, ни авторы не вставляются в соответствующие таблицы.Их оператор вставки обернут в условие, которое должно гарантировать, что они еще не существуют, но, похоже, оно терпит неудачу, и вставка никогда не происходит.Я предполагаю, что это терпит неудачу, потому что теги не помещаются в базу данных, и это вниз в разделе автора, прежде чем он выбросит ошибку.Я знаю, как сделать это с чистым PHP, но я пытаюсь делать это чисто CI ActiveRecord.

Вот заявление, которое я использую:

 if ($this->db->count_all_results() == 0)

И я использую это вместо того, что я обычно использую:

if (mysql_num_rows() == 0)

Я делаюэто неправильно?

Вот моя модель и контроллер (только те функции, которые важны), прокомментированные как могли.

Модель:

function new_book($book, $tags, $authors, $read) {

    // Write book details to books table
    $this->db->insert('books', $book);

    // Write tags to tag table and set junction
    foreach ($tags as $tag) {
        // Check to see if the tag is already in the 'tags' table
        $this->db->get_where('tags', array('tag' => $tag));
        // trying to use this like mysql_num_rows()
        if ($this->db->count_all_results() == 0) {
            // Put it there
            $this->db->insert('tags', $tag);
        }
        // Set the junction
        // I only need the id, so...
        $this->db->select('id');
        // SELECT id FROM tags WHERE tag = $tag
        $query = $this->db->get_where('tags', array('tag' => $tag));
        // INSERT INTO books_tags (book_id, tag_id) VALUES ($book['isbn'], $query->id)
        $this->db->insert('books_tags', array('book_id' => $book['isbn'], 'tag_id' => $query->id));
    }

    // Write authors to author table and set junction
    // Same internal comments apply from tags above
    foreach ($authors as $author) {
        $this->db->get_where('authors', array('author' => $author));
        if ($this->db->count_all_results() == 0) {
            $this->db->insert('authors', $author);
        }
        $this->db->select('id');
        $query = $this->db->get_where('authors', array('author' => $author));
        $this->db->insert('authors_books', array('book_id' => $book['isbn'], 'author_id' => $query));
    }

    // If the user checked that they've read the book
    if (!empty($read)) {
        // Get their user id
        $user = $this->ion_auth->get_user();
        // INSERT INTO books_users (book_id, tag_id) VALUES ($book['isbn'], $user->id)
        $this->db->insert('books_users', array('book_id' => $book['isbn'], 'user_id' => $user->id));
    }

}

Контроллер:

function confirm() {

    // Make sure they got here by form result, send 'em packing if not
            $submit = $this->input->post('details');
    if (empty($submit)) {
        redirect('add');
    }

            // Set up form validation
    $this->load->library('form_validation');
    $this->form_validation->set_error_delimiters('<h3 class="error">', ' Also, you&rsquo;ll need to choose your file again.</h3>');
    $this->form_validation->set_rules('isbn','ISBN-10','trim|required|exact_length[10]|alpha_numeric|unique[books.isbn]');
    $this->form_validation->set_rules('title','title','required');
    $this->form_validation->set_rules('tags','tags','required');

            // Set up upload
    $config['upload_path'] = './books/';
    $config['allowed_types'] = 'pdf|chm';
    $this->load->library('upload', $config);

            // If they failed validation or couldn't upload the file
    if ($this->form_validation->run() == FALSE || $this->upload->do_upload('file') == FALSE) {
        // Get the book from Amazon
                    $bookSearch = new Amazon();
        try {
            $amazon = $bookSearch->getItemByAsin($this->input->post('isbn'));
        } catch (Exception $e) {
            echo $e->getMessage();
        }
                    // Send them back to the form
        $data['image'] = $amazon->Items->Item->LargeImage->URL;
        $data['content'] = 'add/details';
        $data['error'] = $this->upload->display_errors('<h3 class="error">','</h3>');
        $this->load->view('global/template', $data);

            // If they did everything right
            } else {
                    // Get the book from Amazon
        $bookSearch = new Amazon();
        try {
            $amazon = $bookSearch->getItemByAsin($this->input->post('isbn'));
        } catch (Exception $e) {
            echo $e->getMessage();
        }

        // Grab the file info
                    $file = $this->upload->data();

        // Prep the data for the books table
                    $book = array(
            'isbn' => $this->input->post('isbn'),
            'title' => mysql_real_escape_string($this->input->post('title')),
            'date' => $amazon->Items->Item->ItemAttributes->PublicationDate,
            'publisher' => mysql_real_escape_string($amazon->Items->Item->ItemAttributes->Publisher),
            'pages' => $amazon->Items->Item->ItemAttributes->NumberOfPages,
            'review' => mysql_real_escape_string($amazon->Items->Item->EditorialReviews->EditorialReview->Content),
            'image' => mysql_real_escape_string($amazon->Items->Item->LargeImage->URL),
            'thumb' => mysql_real_escape_string($amazon->Items->Item->SmallImage->URL),
            'filename' => $file['file_name']
        );

        // Get the tags, explode by comma or space
                    $tags = preg_split("/[\s,]+/", $this->input->post('tags'));
                    // Get the authors
                    $authors = array();
                    foreach ($amazon->Items->Item->ItemAttributes->Author as $author) {
                        array_push($authors, $author);
                    }
                    // Find out whether they've read it
                    $read = $this->input->post('read');
                    // Send it up to the database
                    $this->load->model('add_model', 'add');
                    $this->add->new_book($book, $tags, $authors, $read);
                    // For now... Later I'll load a view
                    echo 'Success';

    }

}

Может ли кто-нибудь помочь пролить свет на то, что я делаю неправильно?Большое спасибо.

Маркус

Ответы [ 2 ]

0 голосов
/ 28 сентября 2010

Мне удалось выяснить это самостоятельно. Контроллер действительно не изменился, но вот новая модель:

function new_book($book, $tags, $authors, $read) {

    // Write book details to books table
    $this->db->insert('books', $book);

    // Write tags to tag table and set junction
    foreach ($tags as $tag) {
        // Check to see if the tag is already in the 'tags' table
        $query = $this->db->get_where('tags', array('tag' => $tag));
        // trying to use this like mysql_num_rows()
        if ($query->num_rows() == 0) {
            // Put it there
            $this->db->insert('tags', array('tag' => $tag));
        }
        // Set the junction
        // I only need the id, so...
        $this->db->select('id');
        // SELECT id FROM tags WHERE tag = $tag
        $query = $this->db->get_where('tags', array('tag' => $tag));
        $result = $query->row();
        // INSERT INTO books_tags (book_id, tag_id) VALUES ($book['isbn'], $query->id)
        $this->db->insert('books_tags', array('book_id' => $book['isbn'], 'tag_id' => $result->id));
    }

    // Write authors to author table and set junction
    // Same internal comments apply from tags above
    foreach ($authors as $author) {
        $query = $this->db->get_where('authors', array('author' => mysql_real_escape_string($author)));
        if ($query->num_rows() == 0) {
            $this->db->insert('authors', array('author' => mysql_real_escape_string($author)));
        }
        $this->db->select('id');
        $query = $this->db->get_where('authors', array('author' => mysql_real_escape_string($author)));
        $result = $query->row();
        $this->db->insert('authors_books', array('book_id' => $book['isbn'], 'author_id' => $result->id));
    }

    // If the user checked that they've read the book
    if (!empty($read)) {
        // Get their user id
        $user = $this->ion_auth->get_user();
        // INSERT INTO books_users (book_id, tag_id) VALUES ($book['isbn'], $user->id)
        $this->db->insert('books_users', array('book_id' => $book['isbn'], 'user_id' => $user->id));
    }

}
0 голосов
/ 26 сентября 2010

Где вы используете count_all_results (), я думаю, вы хотите использовать num_rows (). count_all_results () фактически создаст запрос SELECT COUNT (*).

Для устранения ваших проблем ...
Если вы хотите проверить, работает ли insert (), используйте disabled_rows () , пример:

var_dump($this->db->affected_rows());

В любой момент вы можете вывести последний запрос с помощью last_query () , пример:

var_dump($this->db->last_query());

Вы также можете включить Profiler , чтобы вы могли видеть все выполняемые запросы, добавив в контроллер:

$this->output->enable_profiler(TRUE);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...