diff options
author | Ryan Bigg <radarlistener@gmail.com> | 2011-10-13 18:04:55 +1100 |
---|---|---|
committer | Ryan Bigg <radarlistener@gmail.com> | 2011-10-13 18:06:00 +1100 |
commit | e537a3fcb1fd16d169889dfbca13eece9cc3bdf1 (patch) | |
tree | 1fc4bbc9dfd4bf2026cf6d7efb4b790eed749f01 /railties/guides | |
parent | e6b2e7fbeab495a9ce0533d3f778cca9cb268597 (diff) | |
download | rails-e537a3fcb1fd16d169889dfbca13eece9cc3bdf1.tar.gz rails-e537a3fcb1fd16d169889dfbca13eece9cc3bdf1.tar.bz2 rails-e537a3fcb1fd16d169889dfbca13eece9cc3bdf1.zip |
[engines guide] change comments resource generation
Totally didn't like where this section was going, so scrapped it.
Scaffold is great for some things (lol) but nested resources is definitely not one of them.
Best to walk people through how to do it right, as they would in the real world
Diffstat (limited to 'railties/guides')
-rw-r--r-- | railties/guides/source/engines.textile | 87 |
1 files changed, 33 insertions, 54 deletions
diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index db2db05e57..e22f3a7ae6 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -201,83 +201,62 @@ If you'd rather play around in the console, +rails console+ will also work just h4. Generating a comments resource -Now that the engine has the ability to create new blog posts, it only makes sense to add commenting functionality as well. +Now that the engine has the ability to create new blog posts, it only makes sense to add commenting functionality as well. To do get this, you'll need to generate a comment model, a comment controller and then modify the posts scaffold to display comments and allow people to create new ones. -To do this, you can run the scaffold generator this time and tell it to generate a +Comment+ resource instead, with the table having two columns: a +post_id+ integer and +text+ text column. +Run the model generator and tell it to generate a +Comment+ model, with the related table having two columns: a +post_id+ integer and +text+ text column. <shell> -$ rails generate scaffold Comment post_id:integer text:text +$ rails generate model Comment post_id:integer text:text +invoke active_record +create db/migrate/[timestamp]_create_blorgh_comments.rb +create app/models/blorgh/comment.rb +invoke test_unit +create test/unit/blorgh/comment_test.rb +create test/fixtures/blorgh/comments.yml </shell> -This generator call will generate almost the same files as it did the first time we called it for generating the +Post+ resource, but this time the files will be called things such as +app/controllers/blorgh/comments_controller.rb+ and +app/models/blorgh/comment.rb+. - -There's a few things wrong with how this generator has worked. It would be better if the comments resource was nested inside the posts resource in the routes, and if the controller created new comment entries inside a post. These are two very easy things to fix up. - -The +resources+ line from this generator is placed into the +config/routes.rb+ by the generator, but you're going to want to have comments nested underneath a post, and so it's a good idea to change these lines in the +config/routes.rb+ file: - -<ruby> -Blorgh::Engine.routes.draw do - resources :comments - - resources :posts - -end -</ruby> - -Into these: - -<ruby> - Blorgh::Engine.routes.draw do - resources :posts do - resources :comments - end - end -</ruby> +This generator call will generate just the necessary model files it needs, namespacing the files under a +blorgh+ directory and creating a model class called +Blorgh::Comment+. -That fixes the routes. For the controller, it's just as easy. When a request is made to this controller, it will be in the form of +post/:post_id/comments+. In order to find the comments that are being requested, the post is going to need to be fetched using something such as: +To show the comments on a post, edit +app/views/posts/show.html.erb+ and add this line before the "Edit" link: -<ruby> -post = Post.find(params[:id]) -</ruby> +<erb> +<%= render @post.comments %> +</erb> -Then to get the comments for this post it would be as simple as: +This line will require there to be a +has_many+ association for comments defined on the +Blorgh::Post+ model, which there isn't right now. To define one, open +app/models/blorgh/post.rb+ and add this line into the model: <ruby> -post.comments +has_many :comments </ruby> -Alternatively, the query to fetch the comments in actions such as the +index+ action would need to be changed from +Comment.all+ into +Comment.find_all_by_post_id(params[:post_id])+. However, the first way is cleaner and so it should be done that way. - -To fetch the post in the controller, add a +before_filter+ into the controller's class definition like this: +Turning the model into this: <ruby> module Blorgh - class CommentsController < ApplicationController - before_filter :load_post - ... + class Post < ActiveRecord::Base + has_many :comments end end </ruby> -This +before_filter+ will call the +load_post+ method before every request that comes into this controller. This method should be defined as a +private+ method after all the actions in the controller: - -<ruby> -module Blorgh - class CommentsController < ApplicationController - before_filter :load_post +Because the +has_many+ is defined inside a class that is inside the +Blorgh+ module, Rails will know that you want to use the +Blorgh::Comment+ model for these objects. - # actions go here +Next, there needs to be a form so that comments can be created on a post. To add this, put this line underneath the call to +render @post.comments+ in +app/views/blorgh/posts/show.html.erb+: - private +<erb> +<%= render "comments/form" %> +</erb> - def load_post - @post = Post.find(params[:post_id]) - end - end -end -</ruby> +Next, the partial that this line will render needs to exist. Create a new directory at +app/views/blorgh/comments+ and in it a new file called +_form.html.erb+ with this content to create the required partial: -With the post being loaded, the queries in the controller need to be altered in order to query within the scope of the relative post. All occurrences of +Comment+ in this controller should now be replaced with +@post.comments+ so that the queries are correctly scoped. +<erb> +<%= form_for [@post, @post.comments.build] do |f| %> + <p> + <%= f.label :text %><br /> + <%= f.text_area :text %> + </p> +<% end %> +</erb> h3. Hooking into application |