2010-09-26 4 views
0

Je suis en train de créer ma première application sur CodeIgniter. C'est aussi la première fois que j'essaie de m'en tenir à OOP et MVC autant que possible. Ça va bien jusqu'ici mais maintenant que j'essaye d'écrire mon premier modèle, j'ai des problèmes. Voici l'erreur que je reçois:Problèmes avec CodeIgniter ActiveRecord

Une erreur de base de données Survenu

Numéro d'erreur: 1064

Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version du serveur MySQL pour la bonne syntaxe à utiliser près 'Castledine' à la ligne 3

SELECT * FROM (authors) OÙ author = Earle Castledine

qui, comme vous voir ci-dessous, se rapporte à la ligne suivante dans mon modèle:

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

Je ne suis pas tout à fait sûr pourquoi il est jeter l'erreur. Est-ce parce que Earle Castledine n'est pas entre guillemets? Si oui, pourquoi CI ne les met-il pas là? Je doute que ce soit le problème, plutôt que de penser que c'est de ma faute, mais je ne suis pas sûr.

J'ai aussi un autre problème. Ni les balises ni les auteurs ne sont insérés dans leurs tables respectives. Leur instruction d'insertion est enveloppée dans un conditionnel censé s'assurer qu'ils n'existent pas déjà, mais cela semble échouer et l'insertion ne se produit jamais. Je suppose que cela échoue parce que les balises ne sont pas mises dans la base de données et qu'elles sont dans la section auteur avant que l'erreur ne soit lancée. Je sais comment le faire avec du PHP pur mais j'essaye de le faire de la manière pure de CI ActiveRecord.

Voici la déclaration que je utilise:

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

Et je me sers qu'au lieu de ce que je normalement utiliser:

if (mysql_num_rows() == 0) 

que je fais mal?

Voici mon modèle et contrôleur (seulement les fonctions qui comptent), commenté du mieux que je pouvais.

Modèle:

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)); 
    } 

} 

Controller:

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'; 

    } 

} 

Quelqu'un pourrait-il aider à faire la lumière sur ce que je fais mal? Merci beaucoup.

Marcus

+0

J'ai compris cela. Je ne peux pas y répondre avant 24 heures, mais ne vous sentez pas obligé de travailler dessus si vous n'aimez pas. Cela dit, je serais intéressé de voir si je le fais tout de suite (je veux dire, ça marche, mais qui sait si c'est correct), alors n'hésitez pas à laisser tomber vos pensées. – Marcus

Répondre

0

J'ai réussi à comprendre cela par moi-même. Le contrôleur n'a pas vraiment changé, mais voici le nouveau modèle:

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

Si vous utilisez count_all_results(), je pense que vous voulez dire utiliser num_rows(). count_all_results() créera en fait une requête SELECT COUNT (*).

Pour le débogage de vos problèmes ...
Si vous voulez tester si un insert() a travaillé, utilisez affected_rows(), par exemple:

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

A tout moment vous pouvez produire ce que la dernière requête avec last_query(), par exemple:

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

Vous pouvez tourner également sur le Profiler donc vous pouvez voir toutes les requêtes en cours d'exécution, en ajoutant dans le contrôleur:

$this->output->enable_profiler(TRUE);