开发者

How to get the post id in rails?

开发者 https://www.devze.com 2023-03-15 21:53 出处:网络
This is is how I have my models define for a simple blog def User has_many :comments, :dependent => :destroy

This is is how I have my models define for a simple blog

def User
  has_many :comments, :dependent => :destroy
  has_many :posts
end

def Post
  belongs_to :user
  has_many :comments
end

def Comment
  belongs_to :user开发者_如何转开发
  belongs_to :post
end

In my Post Controller I have this code so that I can create a comment in the view

  def show
    @post = Post.find(params[:id])
    @comment = Comment.new
    respond_to do |format|
        format.html # show.html.erb
        format.xml  { render :xml => @post }
    end
  end

Then in my Comment#create I have this

  def create
    @comment = current_user.comments.create(params[:comment])
    if @comment.save
      redirect_to home_show_path
    else
      render 'new'
    end
  end

How should I make it so that my comment model can receive the post_id? I have done this in my Post show view as a fix but is there another way that is better?

<%= f.hidden_field :post_id, :value => @post.id %>


There's nothing necessarily wrong with setting the post_id via a hidden field in your form - however it does mean that people could potentially associate their comment with any random post.

A better way might be to use nested resources for the comments of posts. To do this, set the following in your routes.rb file:

resources :posts, :shallow => true do 
  resources :comments
end

Then your form should look like this:

<%= form_for @comment, :url => post_comments_path(@post) do %>
   ...
<% end %>

Which will mean that the form POSTs to the path /post/[:post_id]/comments - which means in turn that the post_id is available to the controller as a param:

def create
   @comment = current_user.comments.new(params[:comment])
   @comment.post = Post.find(params[:post_id])
   if @comment.save
      ...
   end
end

This has the advantage of doing a select for the Post using the post id, and if the Post isn't found, an error will be raised.

It might also be worth rewriting that controller method slightly, so that the Post.find comes first:

def create
   @post = Post.find(params[:post_id])
   @comment = @post.comments.new(params[:comment])
   @comment.user = current_user
   if @comment.save
      ...
   end
end

Hope that helps.


Yes, there is a better way. Use nested resources as described in the official Routing guide or in the Getting Started guide. The Getting Started guide even covers this exact example of posts and comments!


<%= form_for :comment, :url => post_comments_path(@post) do |f| %>

<%= f.text_field :content %>
<%= f.submit%>
<% end %>

In your comment create action you have

def create
@post = Post.find(params[:post_id])
@comment = @post.comments.build(params[:comment])
@comment.user = current_user #if you are using devise or any authentication plugin or you define a current_user helper method
if @comment.save
......
end

if you are using rails 3, in you config/routes.rb do

resources :posts do
resources :comments
end

the first section of the code should be in your post/show.html.erb

0

精彩评论

暂无评论...
验证码 换一张
取 消