1
votes

I have a model called Game, which has a hasMany relationship with a Planet model (which in turn has a belongsTo defined back to the Game model).

Upon creating my first Game record, I use the value of its starting_num_planets field to try to create that many associated Planet records. The GamesController does this by calling a function in the PlanetsController which, each time called, returns an array that matches the Planet model, and should be saveable, which is the next thing the GamesController tries to do.

The Game record is created just fine, but I am somehow getting an invalid SQL syntax error apparently at the point at which I'm trying to access the second controller's function. Which is weird, because I'm not trying to save until a couple of lines later.

Here's the code from the GamesController:

public function newgame() {
        if ($this->request->is('post')) {
            $this->Game->create();
            if ($this->Game->save($this->request->data)) {
                // Add the 'id' element to the Game array and put the whole game record on the session
                $this->request->data['Game']['id'] = $this->Game->getLastInsertID();
                $this->Session->write('Game', $this->request->data);

                // Create the number of planet records indicated by start_num_planets
                $count = 0;
                $planets = array();
                while ($count < $this->request->data['Game']['starting_num_planets']) {
                    $planetData = $this->Game->Planet->generate_planet_data($this->request->data['Game']['id']);
                    $planets[$count] = $planetData;
                    $this->Game->Planet->create();
                    $this->Game->Planet->save($planetData);
                    $count++;
                }

                $this->redirect(array('action' => 'main'));
            } else {
              $this->Session->setFlash('There was a problem creating the game.');
            }
        }
    }

At the line number for this line:

$planetData = $this->Game->Planet->generate_planet_data($this->request->data['Game']['id']);

I am getting:

Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'generate_planet_data' at line 1

SQL Query: generate_planet_data

And I have no idea why, I'm afraid.

Here's the function being called in the PlanetsController:

public function generate_planet_data($gameId) {
    $planetNames = array(1 => 'name1', 2 => 'name2', 3 => 'name3', 4 => 'name4');
    $planetImages = array(1 => '01', 2 => '02', 3 => '03', 4 => '04');
    $planetData = array();
    // game_id is the foreign key, do I have to explicitly state that in the model?
    $planetData['Planet']['game_id'] = $gameId;
    $planetData['Planet']['planet_name'] = $planetNames[rand(1,10)];
    $planetData['Planet']['planet_image_file'] = $planetImages[rand(1,4)];
    return $planetData;
}

The model association in Game.php is simply:

var $hasMany = array(
    'Planet' => array(
        'className' => 'Planet'),
    'Player' => array(
        'className' => 'Player'
    )
);

Can anyone tell what's going wrong? This is my first attempt at using associated models, and it's gone a bit awry! :)

1
where is function generate_planet_data declared?Moyed Ansari
That's in the PlanetsController. (I've just read it should probably be in the Planet model, but I don't think that will solve my problem, even if it's "better" MVC design...Jimbo
see my answer hope this will workMoyed Ansari

1 Answers

2
votes

The problem is that you're calling a missing function here:

$planetData = $this->Game->Planet->generate_planet_data($this->request->data['Game']['id']);

As you said generate_planet_data is on the controller. So you should call it thusly:

$planetData = $this->generate_planet_data($this->request->data['Game']['id']);

As stated in the comments, this logic probably belongs in the Planet model. If you moved it there you would then be able to access it via your original way.