The Slim Framework support forum has moved to http://discourse.slimframework.com. This Tender forum is no longer maintained or monitored.

Creating an object with an has_many()

Shadow Media's Avatar

Shadow Media

05 Feb, 2012 03:49 PM

Hi,

I realise this is more of a Paris or Idiorm problem than a Slim problem, but here goes:

I'm building a prototype with Slim, Paris, Idiorm and Twig on a PHP 5.2/MySQL system.

The application needs to do this: manage Projects and the Events coupled with each Project. A Project is nothing more than an id and a name, an Event is a bit more complicated: id, time (timestamp), name, remarks, project_id. project_id is defined as a foreign key to the id-field in the project table.

Each event has one or more todos, but I'm not yet arrived there regarding routes and forms to fill that up. The database table for the todo's already ready though.

So Event.php has:

<?php
class Event extends Model
{
public function todos() {
    return $this->has_many('Todo');
}

public function project() {
    return $this->belongs_to('Project');
}
}
?>

and Project.php:

<?php
class Project extends Model
{
public function events() {
    return $this->has_many('Event');
}
}
?>

That's for the models. They're all required in index.php, which works without a problem for adding and editing projects. However, for adding an event, it doesn't work. (It does for editing one that's been entered through phpmyadmin...) Here's the route code:

$app->get('/event/add/(:projectid)', 'addEventForm');
function addEventForm($projectid) {
$app = Slim::getInstance();
$projects = Model::factory('Project')->find_many();
return $app->render('event_input.html', array('action_name' => 'Add', 'action_url' => '/avenuel/event/add/' . $projectid, 'projects' => $projects));
}

$app->post('event/add/(:projectid)', 'addEvent');
function addEvent($projectid) {
$app = Slim::getInstance();
$event = Model::factory('Event')->create();
$event->name = $app->request()->post('name');
$event->date = $app->request()->post('date');
$event->project_id = $app->request()->post('project');
$event->remarks = $app->request()->post('remarks');
$event->save();

$app->redirect('/avenuel/project/' . $projectid);
}

Here is the form that's used:

<form action='{{ action_url }}' method='post'>
<h1>{{ action_name }} Event</h1>
<p>
    <label for='name'>Name: </label><br/>
    <input type='text' name='name' value='{{ event.name|default('') }}' id='name' />
</p>
<p>
    <label for='date'>Date: </label><br/>
    <input type="datetime" name='date' value='{{ event.date|default('') }}' placeholder='2012-02-07 13:11:40' id='date' />
</p>
<p>
    <label for='project'>Project:</label><br/>
    <select id='project' name='project'>
        {% for project in projects %}
        <option value='{{ project.id|default(event.project_id) }}'>{{ project.name }}</option>
        {% else %}
        No projects available. <a href='/avenuel/project/add/'>Create one first</a>.
        {% endfor %}
    </select>
</p>
<p>
    <label for='remarks'>Remarks: </label><br/>
    <textarea name='remarks' id='date'>{{ event.remarks|default('') }}</textarea>
</p>
    <input type='submit' value='{{ action_name }} Event' />
</form>

The get works, the post doesn't (I just tried it again: submitting the form to http://labs.shadowmedia.be/avenuel/event/add/8 gives a blank page and there's nothing to see in the logs, nor those of Apache, nor the Slim logs, nor the Paris/Idiorm ones). I think it has to do with the way I want to set the project_id.

So, yeah, this is probably more a Paris/Idiorm bug but perhaps you know how this should work?

  1. Support Staff 1 Posted by Josh Lockhart on 05 Feb, 2012 04:00 PM

    Josh Lockhart's Avatar

    First, I'd do some simple tests to ensure the routing is working as you expect it to.

    Test Routing

    Insert the following code at the very top of your POST /event/add/:id route callback function:

    $app->halt(500, 'Test');
    

    When you POST anything to that route, you should receive an HTTP 500 response with a body that reads "Test". If you do not receive an HTTP 500 response, then your routing is not setup properly. If it works, move on to this next step.

    Error Log

    I need to see your error log to diagnose what is happening. Make sure that you have turned display_errors to on. You can do this at the very top of your index.php file (after you require Slim) with this code:

    error_reporting(E_ALL);
    ini_set('display_errors', '1');
    

    That should display errors as they occur. Also, check your PHP error log for any helpful hints.

    Also, $event->save(); will return true or false; it may be worth checking the return value. Let me know.

    Josh

  2. 2 Posted by Shadow Media on 05 Feb, 2012 04:34 PM

    Shadow Media's Avatar

    The halting doesn't even work: HTTP/1.1 405 Method Not Allowed. Which baffles me as I don't see anything wrong with the code in index.php.

  3. 3 Posted by Shadow Media on 05 Feb, 2012 04:39 PM

    Shadow Media's Avatar

    Ha, I think I got it, a missing slash:

    $app->post('event/add/(:projectid)', 'addEvent');

    which should have been:

    $app->post('/event/add/(:projectid)', 'addEvent');

    The halt works now!

    Josh: Thanks for the testing tips!

  4. Support Staff 4 Posted by Josh Lockhart on 05 Feb, 2012 04:44 PM

    Josh Lockhart's Avatar

    Nice. Yes, you always need to have leading forward slashes for each route you define. The rest of your code should be fine. Closing this out. If you still have issues, just leave a new reply and this thread will re-open.

    Best,
    Josh

  5. Josh Lockhart closed this discussion on 05 Feb, 2012 04:44 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac