在我的应用程序中添加注释时路由错误

时间:2015-11-26 22:33:13

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 comments

我已经完成了Michael Hartl的“Ruby on Tutorials”一书,现在我试图在微博中添加评论但是当我试图发表评论时,我有一个错误

No route matches [POST]

我找不到有什么问题?

我还想知道我的关联在模型之间是否正确? (我想在帖子上创建Facebook评论等评论)

comments_controller

class CommentsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy

  def create
    user = User.find_by(params[:id])
    micropost = user.microposts.build(params[:micropost])

    @comment = Comment.new(params[:comment])
    @comment.micropost_id = micropost_id
    @comment.user = current_user

    if @comment.save
      flash[:success] = "Comment created!"
      redirect_to root_url
    else
      render 'static_pages/home'
    end
  end
end

comment.html.erb

<h5>Comments<h5>
<div class="comment">
  <% @user.comments.each do |comment| %>
  <p><%= comment.comment %></p>
  <%= time_ago_in_words(comment.created_at) %> ago.
  <%end%>
</div>

_comment_form.html.erb

<%= form_for :comment do |f| %>
  <%= f.text_area :comment_comment, :size => "40x5", placeholder: "Comment..." %>
  <%= f.submit "Post", class: "btn btn-primary" %>
  <span class="picture">
    <%= f.file_field :picture, accept:'image/jpeg,image/gif,image/png' %>
  </span>
<% end %>

_micropost.html.erb

<li id="micropost-<%= micropost.id %>">
  <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
  <span class="user"><%= link_to micropost.user.name, micropost.user %></span>
  <span class="content">
    <%= micropost.content %>
    <%= image_tag micropost.picture.url if micropost.picture? %>
  </span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(micropost.created_at) %> ago.
    <% if current_user?(micropost.user) %>
      <%= link_to "delete", micropost, method: :delete,
                                   data: { confirm: "You sure?" } %>
    <% end %>
  </span>
  <ol>
    <%= render "comments/comment" %>
  </ol>
  <%= render 'shared/comment_form', micropost: micropost %>
</li>

create_comment.rb

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.text :comment
      t.references :user, index: true, foreign_key: true
      t.references :micropost, index: true, foreign_key: true
      t.timestamps null: false
    end
    add_index :comments, [:user_id, :micropost_id, :created_at]
  end
end

comment.rb

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :micropost
end

micropost.rb

class Micropost < ActiveRecord::Base
  belongs_to :user
  has_many :comments
end

user.rb

class User < ActiveRecord::Base
  has_many :microposts, dependent: :destroy
  has_many :comments
end

route.rb

resources :microposts, only: [:create, :destroy] do
  member do
    resources :comments, only: [:create, :destroy] 
  end
end

2 个答案:

答案 0 :(得分:1)

您可以将form_for更改为此

<%= form_for([micropost, micropost.comments.build]) do |f| %>

<%= form_for(@comment, :url => micropost_comments_path(micropost.id)) do |f| %>

然后您必须将routes.rb更改为:

resources :microposts, only: [:create, :destroy] do
  resources :comments, only: [:create, :destroy]
end

这是如何创建comments in article的示例 我希望这能帮到你

答案 1 :(得分:0)

这似乎非常复杂。创建嵌套资源可以简单地完成:

<%= form_for([micropost, micropost.comments.build]) do |f| %>

这将为表单操作生成网址/microposts/13/comments

让我们修复路线:

resources :microposts, shallow: true, only: [:create, :destroy] do
  resources :comments, only: [:create, :destroy]
end

在Rails中嵌套资源丰富的路由时,不应使用member domembercollection用于向标准CRUD谓词之外的资源添加其他方法。 shallow: true表示rails不会嵌套“单独”路由,如show,edit,destroy,它们作用于单个资源。

然后我们清理控制器:

class CommentsController < ApplicationController

  before_action :set_micropost, only: [:index, :new, :create]

  # POST /microposts/:micropost_id/comments
  def create
    @comment = @micropost.comments.build(comment_params) do |c|
      c.user = current_user
    end

    if @micropost.save
      # ...
    else
      # ...
    end
  end

  def comment_params
    params.require(:comment).permit(:comment_comment, :picture)
  end

  def set_micropost
    @micropost = Micropost.find(params[:micropost_id])
  end
end