SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    controller structure

    Hello,

    I am building a small test application for learning RoR. I understand
    most of what is going on and all my relations is set up correctly.
    (tested with console) I can't figure out when to spilt out models into
    separate controllers. Is it overkill to create a controller for each
    model? Let me give an example.

    Users -> Pos -> Comments

    The show post page will display the Post and it's comments. At the
    moment I got a Post controller with CRUD (R both post and comments)
    and a Comments controller with CUD. Would it make sense to merge these
    two controllers into one controller?

    Best regards.
    Asbjørn Morell.

  2. #2
    SitePoint Evangelist
    Join Date
    Feb 2006
    Location
    Worcs. UK
    Posts
    404
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I believe it is definitely a good idea to move away from the starting point of each model having a controller.

    To do this successfully you need to consider what a controller does. That is, the controller organises and gathers all the data together to present to the views associated with it. With this in mind, the number of controllers depends more on how you want to organise your presentation of data within views rather than the number of models.

    With posts and comments, the question I think you need to ask yourself is "will I need to organise and present the posts and comments data separately?". I expect that really comes down to will you want to provide standalone comment lists and individual views.

    If the answer is 'no', and that comments will only ever be viewed in close association with posts, then I would recommend that you have a single controller.

    If the answer is 'yes' and you definitely want to be able to view things like all the comments submitted by a single user, then I'd go for for two controllers (though in this example, I'd start wondering whether to go for two controllers (for users and posts) and three models (User, Post, Comment).

    There is a grey area between the two. The new and edit comments views may be standalone and therefore there'd be a case for them belonging to a comments controller.

    Personally, I probably want comments to always be viewed with their parent post, and therefore I'd start with one controller. Then if the number comment only methods grew to more than one or two, or the controller coding got too complex, I'd consider stripping out the comment rich methods and putting them into their own controller at that time.

    So personally, I'd start with one. It can easily be split into two at a later point if required.

  3. #3
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for your detailed answer Reggie. This was exactly the kind of feedback I was hoping for. I like you approach with using the controllers for organizing the models. I want comments to always be CRUD from within their parent post - just as you suggest. The only problem I see with using the same controller for my posts/comments models is that I will have to watch my method naming. (newpost, newcomment, delcomment, delpost. etc.)

    I will go on with this approach and see how it goes

    Best regards.
    Asbjørn Morell.

  4. #4
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you can use ajax then you can have one controller per model. For example, the view post page could have an ajax form that submits to the comments controller.

    That said, I think it's a bad thing if you have to change the behavior of your application to be able to structure your code in a nice way.

    So Rails has a nice built-in solution for you: nested resources.

    Put this in your routes.rb file:

    Code ruby:
    map.resources :posts do |posts|
      posts.resources :comments
    end

    This gives you the following urls:

    Code:
    /posts
    /posts/3
    /posts/3/comments/create
    But you can still have separate controllers for posts and comments.

    Code ruby:
    class PostsController < ApplicationController
      # /posts
      def index
        @posts = Post.find(:all)
      end
     
      # /posts/3
      def show
        @post = Post.find(params[:id])
      end
    end
     
    class CommentsController < ApplicationController
      # /posts/3/comments/create
      def create
        @post = Post.find(params[:post_id]) # params[:post_id] contains the "3" from the url
        @comment = @post.comments.new(params[:comment])
        ...
      end
    end

    This is useful if you want to have two controllers. I cannot think of any reason why you'd want to merge the two controllers into one, but there might be a good reason depending on your application. For this situation of posts-comments, nested routes are the standard way of doing this in Rails.

  5. #5
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I tried your example and /posts/1/comments/create throws me an error:

    Unknown action No action responded to show

    from development log:
    Parameters: {"action"=>"show", "id"=>"create", "controller"=>"comments", "post_id"=>"1"}

    Looks like the action still is "show" (should be create) Any ideas?

  6. #6
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You have to POST to the url, or else it's trying to show you a comment with id="create" (which obviously doesn't exist). So basically it only works if you submit a form to that url. On a blog you'd put this form ("comment on this post") beneath the post and beneath the comments. This form submits (posts) to /posts/1/comments/create.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •