Hi Tom,
On 2.2.2005, at 16:05, Tom Rathbone wrote:
> Hi,
>
> Building a simple blog, each post has a number of comments. I want
> to create a new action call add_comment it should create a new comment
> in the comments table with the post_id field pointing to current post.
> How can I get the method to recognise the post that the comment is
> being created for? Should I be including a hidden form field?
Yes, that''s the easiest way:
<%= hidden_field "post", "id", "value"
=> @post.id %>
And then in the controller:
def add_comment
@post = Post.find(params["post"]["id"])
@comment = Comment.new(@params["comment"])
@post.comments << @comment
end
I put in some inline suggestions.
HTH,
Jarkko
> How
> can I secure this, i.e. assure that the new comment is being made on a
> valid post?
>
> Thanks,
>
> Tom.
>
> p.s. I am new to MVC thinking.. is this the right place for the
> add_comment action?
>
>
> VIEW
> ---
> <html>
> <head>
> <title>Rails Blog</title>
> </head>
>
> <body>
> <h1><%= @post.title %> <id: <%= @post.id
%>></h1>
> <p><%= @post.body %></p></br>
> <%= comments = @post.comments; comments.length %> comments:
<br/>
<%= @post.comments.length %>
> <% comments.each do |comment| %>
<% for comment in @post.comments %>
> Comment:
> <%= comment.text %><br/>
> <% end %>
> <hr/>
>
> <form action="add_comment" method="post">
<%= start_form_tag :action => "add_comment" %>
>
> Name:
> <%= text_field "new_comment", "name",
"size" => 20 %><br/>
> Comment:
> <%= text_area "new_comment", "text",
"cols" => 20 %><br/>
Add this here: <%= hidden_field "post", "id",
"value" => @post.id %>
> <input type="submit" value="Add Comment">
> </form>
>
> </body>
> </html>
>
> CONTROLLER
> ----------
> class PostController < ApplicationController
> model :post
> scaffold :post
>
> def list
> @posts = Post.find_all
@new_comment = Comment.new
> end
>
> def add_comment
> comment = Comment.new
@comment = Comment.new(@params["new_comment"])
@post = Post.find(@params["post"])
> comment.attributes = @params[''new_comment'']
You can leave this away if you put the params right in the .new call
>
> if comment.save
> redirect_to(:action => "show")
> else
> render_text "Couldn''t add new item"
> end
if @comment.valid?
Comment.transaction do
raise "rollback" unless @comment.save
@post.comments << @comment
flash["notice"] = ''Comment added.''
redirect_to :action => "show", :id => @post.id
end
else
render_text "Blah"
end
> end
> end
>
> MODEL
> --------
> class Post < ActiveRecord::Base
> has_many :comments, :class_name => "Comment"
> end
>
> class Comment < ActiveRecord::Base
> belongs_to :post, :class_name => "Post", :foreign_key =>
"post_id"
> end
You don''t need to set :class_name explicitly, Rails can guess it from
the first parameter (e.g :comments).
>
> DB
> ----
>
> CREATE TABLE `posts` (
> `id` int(11) unsigned NOT NULL auto_increment,
> `title` text collate utf8_bin NOT NULL,
> `body` text collate utf8_bin NOT NULL,
> `author` int(11) NOT NULL default ''0'',
> PRIMARY KEY (`id`)
> )
>
> INSERT INTO `posts` VALUES (1, ''Hello world.'',
''Testing 1 2 3\r\nThis
> is a post'', 0);
> INSERT INTO `posts` VALUES (2, ''Post number 1'',
''Whooo!'', 0);
>
>
> CREATE TABLE comments (
> id int(11) unsigned NOT NULL auto_increment,
> post_id int(11) NOT NULL default ''0'',
> name varchar(100) collate utf8_bin NOT NULL default '''',
> `text` text collate utf8_bin NOT NULL,
> PRIMARY KEY (id)
> )
>
> # one comment for each post
> INSERT INTO `comments` VALUES (1, 1, ''Tom'',
''Comment on post 1'');
> INSERT INTO `comments` VALUES (2, 2, ''comment on 2'',
''Comment on post
> 2'');
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
--
Jarkko Laine
http://jlaine.net
http://odesign.fi
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails