0
votes

I have a simple blog application with the following associations:

Post hasMany Comment

Comment belongsTo Post

In the view for a post (PostsController::view action), existing comments are shown and there is a twitter modal popup which shows a form to add a comment.

What do I need to do to insert a new comment in the comments table, from the posts controller view action? How can I call one controller action from another?

5
If you load the add comment form in a modal, why can’t your form in that modal have an action of /comments/add or similar?Martin Bean
Hew rote "model", not "modal".Mark

5 Answers

4
votes

1. Create a controller action

Create a controller action used to process comment form submissions. This is a very simple (and dumb) example - enhance as required:

// Controller/CommentsContorller.php
class CommentsController extends AppController {

    public $components = array('RequestHandler');

    public function add() {
        $return = false;
        if ($this->request->data) {
            $return = $this->Comment->save($this->request->data);
        }

        if ($this->RequestHandler->isAjax()) {
            // return error or result as json
        }

        // fallback in case of direct access
        $this->redirect($this->referer());
    }
}

2. Create a comment form

Create a comment form, since you mention in the question using bootstrap modals, wrap the form in appropriate markup:

// View/Elements/comment_form.ctp
<!-- Button trigger modal -->
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
  Add a comment
</button>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>     
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        <?php
        echo $this->Form->create('Comment', array('url' => '/comments/add/'));
        echo $this->Form->inputs(array(
            'comment',
            'author'
        ));
        echo $this->Form->submit('add comment');
        ?>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

3. Include it in the relevant view file

With the element created, just include it somewhere appropriate, such as at the end of the posts index:

// View/Posts/index.ctp
...
echo $this->element('comment_form');

4. Submit by javascript

This step is optional.

With the above working the comment form should show up (via javascript) when clicking add comment but since it's a normal form it will be a normal http request upon submission. The comment form already works, don't change it, but most likely you'll want to add a form submission handler so that the form is submitted by ajax. In this way the user is not redirected away from the page.

Something like:

$('form#CommentAdd').submit(function(e) {
    e.preventDefault();

    $.post(
        $(this).attr('href'), 
        $(this).serialize(),
        function(result) {
            ...
            $('#myModal').modal('hide');
        }
    );
});
1
votes

You can use requestAction function of cakephp for calling one controllers action in another controller.

If you have PostsController and action is comment, you can add comment data in CommentsController using requestAction.

Below are the examples of use of requestAction

$response = $this->requestAction('/comments/add/comment:New comment/id:3');

$comments = $this->requestAction('/comments/latest');
0
votes

You simply don't do that because it would violate the MVC design pattern.

There are several ways to solve this, the most simple would be to post your comment to /comments/add and redirect the user back to from where he came from. You can show a flash message if the comment was added correctly or not.

The alternative would be to post it to the same view (assuming posts/view) and intercept the post in the beforeFilter and to check if a comment record is present and if yes save it through the association Post hasMany Comment. This comments plugin solves it this way.

0
votes

you can try something like that to call in model

$myvar = ClassRegistry::init('OtherModel')->anyMethod();
$this->set(compact('myvar'));

you can also pass the any data with ClassRegistry::init('OtherModel')->anyMethod($data);

you can also use loadModel to get/use in controller

$this->loadModel('Model');
$data = $this->Model->function();
0
votes

You should not do that because calling a controller function from another controller just doesn't make sense in CakePHP: it does not follows the MVC design pattern and if you want to program in violation of that pattern (which is of course allowed but not really recommended), you shouldn't use a MVC based framework. What you want to do can be done without that kind of hack. You seem to be starting with CakePHP, so don't start with bad habits!

You question is hard to answer because it is so unspecific. You should refer to the CakePHP documentation, specifically the section Saving Your Data. Look also on the saveAll and saveMany methods.