0

I read this post and it was helpful for the first step, now I'm at the second step. I need help with the controllers and forms.

Let's say this is my model:

User
 has_many :posts
 has_many :comments

Post
 belongs_to :user
 has_many :comments

Comment
 belongs_to :user
 belongs_to :post

And these are my tables:

User
 id

Post
 id
 user_id

Comment
 id
 user_id
 post_id

In the initial post, the User ID gets added with the content automatically by adding this to the create section in the controller:

@post = current_user.post.build(params[:post])

If the comment belongs to both the user and the post, how do I make it automatically add the post_id as well as the user_id? Currently, I can only seem to make it insert the user_id by doing this:

current_user.comments.build(params[:comment])

I'm new to rails. I don't think the best way would be to make the field accessible and add a hidden field in the form, isn't there another way?

These are my updated routes:

                  users GET    /users(.:format)                                           users#index
                        POST   /users(.:format)                                           users#create
               new_user GET    /users/new(.:format)                                       users#new
              edit_user GET    /users/:id/edit(.:format)                                  users#edit
                   user GET    /users/:id(.:format)                                       users#show
                        PUT    /users/:id(.:format)                                       users#update
                        DELETE /users/:id(.:format)                                       users#destroy
               sessions POST   /sessions(.:format)                                        sessions#create
            new_session GET    /sessions/new(.:format)                                    sessions#new
                session DELETE /sessions/:id(.:format)                                    sessions#destroy
   Post_comments GET    /posts/:Post_id/comments(.:format)          comments#index
                        POST   /posts/:Post_id/comments(.:format)          comments#create
 new_Post_Comment GET    /posts/:Post_id/comments/new(.:format)      comments#new
edit_Post_Comment GET    /posts/:Post_id/comments/:id/edit(.:format) comments#edit
     Post_Comment GET    /posts/:Post_id/comments/:id(.:format)      comments#show
                        PUT    /posts/:Post_id/comments/:id(.:format)      comments#update
                        DELETE /posts/:Post_id/comments/:id(.:format)      comments#destroy
          posts GET    /posts(.:format)                                   posts#index
                        POST   /posts(.:format)                                   posts#create
       new_Post GET    /posts/new(.:format)                               posts#new
      edit_Post GET    /posts/:id/edit(.:format)                          posts#edit
           Post GET    /posts/:id(.:format)                               posts#show
                        PUT    /posts/:id(.:format)                               posts#update
                        DELETE /posts/:id(.:format)                               posts#destroy
                   root        /                                                          static_pages#home
                 signup        /signup(.:format)                                          users#new
                 signin        /signin(.:format)                                          sessions#new
                signout DELETE /signout(.:format)                                         sessions#destroy
                  start        /start(.:format)                                           posts#new
Community
  • 1
  • 1
Nathan McKaskle
  • 2,926
  • 12
  • 55
  • 93
  • 1
    You can send attributes to the build method: `current_user.comments.build(params[:comment], post_id: params[:id])` Assuming that `params[:id]` contains the post id (I guess you're using this part of code here `/posts/[:id]/comments/new`) – MrYoshiji Dec 04 '12 at 19:42

1 Answers1

2

The best way that I've found to do commenting has been covered by Ryan Bates on railscasts here

class Comment < ActiveRecord::Base
  attr_accessible :content
  belongs_to :commentable, polymorphic: true
end

class Post < ActiveRecord::Base
  attr_accessible :content, :name
  has_many :comments, as: :commentable
end

And you can pass current_user when actually building the comments in the controller, or pass it as a hidden field, a few different options available to you.

Edit for routes: Ah that's why, you're comments and your posts aren't hooked into each other at all. in your routes where you do resources :post change it do

resources :post do 
  resources :comments 
end

You need to associate the comments to the posts if you're doing Post.comments.build If you're doing current_user.comments.build you'll need to do this in your routes

resources :user do
  resources :comments
end
Magicmarkker
  • 1,063
  • 7
  • 25
  • Oh I saw that episode but it didn't seem relevant to this situation, since it doesn't involve other models. I may need to know more about what I need to put in the controller, than in the models. – Nathan McKaskle Dec 04 '12 at 19:52
  • You can always add more attributes to your controller like `current_user.comments.build(params[:comment], post_id: params[:id])` or `Post.comments.build(params[:comment], post_id: params[:id)` depending on what your routes look like – Magicmarkker Dec 04 '12 at 20:45
  • I posted my routes above, what needs to change there because this way isn't working too well. – Nathan McKaskle Dec 05 '12 at 15:00
  • Nope, it adds functionality to the posts routes, so your regular post routes will be the same, you'd just get additional /post/:id/comments/:comment_id and stuff like that. – Magicmarkker Dec 05 '12 at 15:32
  • Yeah it's now trying to find a /comments route after posting a reply. – Nathan McKaskle Dec 05 '12 at 15:39
  • I'm trying to get it to stay on the same page as the post, and show the new comment underneath, rather than going to a page full of comments. I'm probably going about this all wrong. – Nathan McKaskle Dec 05 '12 at 15:42
  • The route doesn't necessarily mean its going to a new page. You can have the form on the post page, and you can render the comments list partial on the posts page too. That's how partials work :) – Magicmarkker Dec 05 '12 at 15:44
  • When posting a comment, I get No route matches [POST] "/comments". The url in the browser is at localhost:3000/comments. I think I'm close, but missing something. – Nathan McKaskle Dec 05 '12 at 15:53
  • You're form isn't using the correct url from the routes that were generated. I suggest you read up on routing [http://guides.rubyonrails.org/routing.html](http://guides.rubyonrails.org/routing.html) as that seems to be your biggest hurdle in this entire process. – Magicmarkker Dec 05 '12 at 15:55
  • Thanks for all your help. The form is in the /posts folder and is included in the show post page. (/posts/show.html.erb) The form to comment is underneath the content of the post itself. Just like these comments on your answer. – Nathan McKaskle Dec 05 '12 at 18:01