Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>Quick Fix</h2> <p>The RouteMatch object tries to dispatch <code>ActivitiesController::updateAction</code> but you have defined <code>ActivitiesController::update</code> That's due to you using a Restful Controller. the <code>Controller::update</code>-Method is specifically tied to <code>PUT</code>-Requests. You need to define an extra method to handle updates via <code>POST</code>-Requests.</p> <p>I suggest you define <code>ActivitiesController::updateAction</code>, make clear in the docblock it is meant to handle POST-Update requests and refactor both <code>::updateAction</code> and <code>::update</code> to share as much common helper-methods as possible for a fast solution.</p> <h2>Common URI Structur information</h2> <p>As a nice information to have when you start developing RESTful applications/APIs: The ruby community suggests the following url-structure for your resources:</p> <pre><code># These are restful /resource GET (lists) | POST (creates) /resource/:id PUT (updates) | DELETE (deletes) # these are just helpers, not restful, and may accept POST too. /resource/new GET (shows the create-form), POST /resource/:id/edit GET (shows the update-form), POST </code></pre> <h2>Detailed Problem Analysis</h2> <p>A restful update will be sent by an consumer via <code>PUT</code>, but browsers sending HTML-forms may only send <code>GET</code> or <code>POST</code> requests. You should never use <code>GET</code> to create something. So you have to use <code>POST</code> in a forms-context.</p> <p>Looking at the problem from an architectural perspective a multitude of possibilities emerge, depending on how big your application is.</p> <ul> <li>For a small application, tight integration (formhandling and API handling in the controller) apply best.</li> <li>Getting bigger you may want to split up API-Controllers (only restful actions) from Helper-Controllers (form, website handling) which talk to your API-Controllers</li> <li>Being big (multitude of API-Users) you will want to have dedicated API Servers and dedicated Website Servers (independent applications!). In this case your website will consume the API serverside (thats what twitter is doing). API Servers and Website Servers still may share libraries (for filtering, utilities).</li> </ul> <h2>Code Sample</h2> <p>As an educational example I made <a href="https://gist.github.com/Silone/5019600" rel="nofollow">an gist to show how such a controller could look like</a> in principle. This controller is a) untested b) not production ready and c) only marginally configurable.</p> <p>For your special interest here two excerpts about updating:</p> <pre><code>/* the restful method, defined in AbstractRestfulController */ public function update($id, $data) { $response = $this-&gt;getResponse(); if ( ! $this-&gt;getService()-&gt;has($id) ) { return $this-&gt;notFoundAction(); } $form = $this-&gt;getEditForm(); $form-&gt;setData($data); if ( ! $form-&gt;isValid() ) { $response-&gt;setStatusCode(self::FORM_INVALID_STATUSCODE); return [ 'errors' =&gt; $form-&gt;getMessages() ]; } $data = $form-&gt;getData(); // you want the filtered &amp; validated data from the form, not the raw data from the request. $status = $this-&gt;getService()-&gt;update($id, $data); if ( ! $status ) { $response-&gt;setStatusCode(self::SERVERSIDE_ERROR_STATUSCODE); return [ 'errors' =&gt; [self::SERVERSIDE_ERROR_MESSAGE] ]; } // if everything went smooth, we just return the new representation of the entity. return $this-&gt;get($id); } </code></pre> <p>and the <code>editAction</code> which satisfies browser-requests:</p> <pre><code>public function editAction() { /* * basically the same as the newAction * differences: * - first fetch the data from the service * - prepopulate the form */ $id = $this-&gt;params('id', false); $dataExists = $this-&gt;getService()-&gt;has($id); if ( ! $dataExists ) { $this-&gt;flashMessenger()-&gt;addErrorMessage("No entity with {$id} is known"); return $this-&gt;notFoundAction(); } $request = $this-&gt;getRequest(); $form = $this-&gt;getEditForm(); $data = $this-&gt;getService()-&gt;get($id); if ( ! $request-&gt;isPost() ) { $form-&gt;populateValues($data); return ['form' =&gt; $form]; } $this-&gt;update($id, $request-&gt;getPost()-&gt;toArray()); $response = $this-&gt;getResponse(); if ( ! $response-&gt;isSuccess() ) { return [ 'form' =&gt; $form ]; } $this-&gt;flashMessenger()-&gt;addSuccessMessage('Entity changed successfully'); return $this-&gt;redirect()-&gt;toRoute($this-&gt;routeIdentifiers['entity-changed']); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload