Ruby on rails 编辑。。。ActionView::Template::错误(没有路由匹配项…缺少必需的键:[:注释\u id])

Ruby on rails 编辑。。。ActionView::Template::错误(没有路由匹配项…缺少必需的键:[:注释\u id]),ruby-on-rails,Ruby On Rails,当我访问photos/show.html.erb视图时,我从Heroku日志中得到以下错误: ActionView::Template::Error(没有路由匹配{:action=>“index”,:comment\u id=>nil,:controller=>“cflags”,:photo\u id=>“100”}缺少必需的键:[:comment\u id]) 我有非常基本的Photo和Comment模型可以正常工作,然后我构建了一个Cflag模型,用于标记注释。我使用@photo.comme

当我访问
photos/show.html.erb
视图时,我从Heroku日志中得到以下错误:

ActionView::Template::Error(没有路由匹配{:action=>“index”,:comment\u id=>nil,:controller=>“cflags”,:photo\u id=>“100”}缺少必需的键:[:comment\u id])

我有非常基本的
Photo
Comment
模型可以正常工作,然后我构建了一个
Cflag
模型,用于标记注释。我使用
@photo.comments
照片/show.html.erb
视图中列出评论

显示:

# photos/show.html.erb

<% @photo.comments.each do |comment| %>
  <%= form_for(comment, url: photo_comment_cflags_path(@photo, comment)) do |f| %>
    <%= f.hidden_field :user_id, value: current_user.id %>
    <%= f.submit "Report Inappropiate" %>
  <% end %>
<% end %> 
class CflagsController < ApplicationController
before_action :logged_in_user

def new
end

def create
  @comment = Comment.find(params[:comment_id])
  @cflag = @comment.cflags.build(cflag_params)
    if @cflag.save
      if @comment.cflags_count > 1
        @comment.update_attribute(:approved, false)  
        flash[:success] = "Flag created! Comment ##{@comment.id} has been removed for review. Thank you for your feedback"
        redirect_to :back
      else    
        flash[:success] = "Flag created! Thank you for your feedback"
        redirect_to :back
      end
    else
      redirect_to :back, notice: @cflag.errors.full_messages  
    end    
  end    

  private 
    def cflag_params
      params.require(:cflag).permit(:user_id, :comment_id).merge(user_id: current_user.id)
    end
end
resources :photos do
  resources :comments, only: [:create, :edit, :destroy] do
    resources :cflags, only: :create
  end  
end
    photo_comment_cflags GET        /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#index
                         POST       /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#create
 new_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/new(.:format)      cflags#new
edit_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id/edit(.:format) cflags#edit
     photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#show
                         PATCH      /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         PUT        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         DELETE     /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#destroy
def show
  @photo = Photo.approved.find(params[:id])
end
def create
   @photo = Photo.find(params[:photo_id])
   @comment = @photo.comments.build(comment_params)
   @comment.save
   respond_to do |format|
     format.html { redirect_to :back }
     format.js 
   end 
end   
class Cflag < ActiveRecord::Base
  belongs_to :comment, counter_cache: true
  belongs_to :user, counter_cache: true
  validates :user_id, presence: true 
  validates :comment_id, presence: true
  validates :user_id, uniqueness: { 
    scope: [:comment_id],
    message: 'You can only flag a comment once. Thank you for your feedback.'
  }
  default_scope -> { order(created_at: :desc) }
end
create_table "cflags", force: :cascade do |t|
  t.integer  "comment_id"
  t.integer  "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "cflags", ["comment_id"], name: "index_cflags_on_comment_id"
add_index "cflags", ["user_id"], name: "index_cflags_on_user_id"
铁路线路:

# photos/show.html.erb

<% @photo.comments.each do |comment| %>
  <%= form_for(comment, url: photo_comment_cflags_path(@photo, comment)) do |f| %>
    <%= f.hidden_field :user_id, value: current_user.id %>
    <%= f.submit "Report Inappropiate" %>
  <% end %>
<% end %> 
class CflagsController < ApplicationController
before_action :logged_in_user

def new
end

def create
  @comment = Comment.find(params[:comment_id])
  @cflag = @comment.cflags.build(cflag_params)
    if @cflag.save
      if @comment.cflags_count > 1
        @comment.update_attribute(:approved, false)  
        flash[:success] = "Flag created! Comment ##{@comment.id} has been removed for review. Thank you for your feedback"
        redirect_to :back
      else    
        flash[:success] = "Flag created! Thank you for your feedback"
        redirect_to :back
      end
    else
      redirect_to :back, notice: @cflag.errors.full_messages  
    end    
  end    

  private 
    def cflag_params
      params.require(:cflag).permit(:user_id, :comment_id).merge(user_id: current_user.id)
    end
end
resources :photos do
  resources :comments, only: [:create, :edit, :destroy] do
    resources :cflags, only: :create
  end  
end
    photo_comment_cflags GET        /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#index
                         POST       /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#create
 new_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/new(.:format)      cflags#new
edit_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id/edit(.:format) cflags#edit
     photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#show
                         PATCH      /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         PUT        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         DELETE     /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#destroy
def show
  @photo = Photo.approved.find(params[:id])
end
def create
   @photo = Photo.find(params[:photo_id])
   @comment = @photo.comments.build(comment_params)
   @comment.save
   respond_to do |format|
     format.html { redirect_to :back }
     format.js 
   end 
end   
class Cflag < ActiveRecord::Base
  belongs_to :comment, counter_cache: true
  belongs_to :user, counter_cache: true
  validates :user_id, presence: true 
  validates :comment_id, presence: true
  validates :user_id, uniqueness: { 
    scope: [:comment_id],
    message: 'You can only flag a comment once. Thank you for your feedback.'
  }
  default_scope -> { order(created_at: :desc) }
end
create_table "cflags", force: :cascade do |t|
  t.integer  "comment_id"
  t.integer  "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "cflags", ["comment_id"], name: "index_cflags_on_comment_id"
add_index "cflags", ["user_id"], name: "index_cflags_on_user_id"
照片控制器:

# photos/show.html.erb

<% @photo.comments.each do |comment| %>
  <%= form_for(comment, url: photo_comment_cflags_path(@photo, comment)) do |f| %>
    <%= f.hidden_field :user_id, value: current_user.id %>
    <%= f.submit "Report Inappropiate" %>
  <% end %>
<% end %> 
class CflagsController < ApplicationController
before_action :logged_in_user

def new
end

def create
  @comment = Comment.find(params[:comment_id])
  @cflag = @comment.cflags.build(cflag_params)
    if @cflag.save
      if @comment.cflags_count > 1
        @comment.update_attribute(:approved, false)  
        flash[:success] = "Flag created! Comment ##{@comment.id} has been removed for review. Thank you for your feedback"
        redirect_to :back
      else    
        flash[:success] = "Flag created! Thank you for your feedback"
        redirect_to :back
      end
    else
      redirect_to :back, notice: @cflag.errors.full_messages  
    end    
  end    

  private 
    def cflag_params
      params.require(:cflag).permit(:user_id, :comment_id).merge(user_id: current_user.id)
    end
end
resources :photos do
  resources :comments, only: [:create, :edit, :destroy] do
    resources :cflags, only: :create
  end  
end
    photo_comment_cflags GET        /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#index
                         POST       /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#create
 new_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/new(.:format)      cflags#new
edit_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id/edit(.:format) cflags#edit
     photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#show
                         PATCH      /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         PUT        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         DELETE     /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#destroy
def show
  @photo = Photo.approved.find(params[:id])
end
def create
   @photo = Photo.find(params[:photo_id])
   @comment = @photo.comments.build(comment_params)
   @comment.save
   respond_to do |format|
     format.html { redirect_to :back }
     format.js 
   end 
end   
class Cflag < ActiveRecord::Base
  belongs_to :comment, counter_cache: true
  belongs_to :user, counter_cache: true
  validates :user_id, presence: true 
  validates :comment_id, presence: true
  validates :user_id, uniqueness: { 
    scope: [:comment_id],
    message: 'You can only flag a comment once. Thank you for your feedback.'
  }
  default_scope -> { order(created_at: :desc) }
end
create_table "cflags", force: :cascade do |t|
  t.integer  "comment_id"
  t.integer  "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "cflags", ["comment_id"], name: "index_cflags_on_comment_id"
add_index "cflags", ["user_id"], name: "index_cflags_on_user_id"
评论控制器:

# photos/show.html.erb

<% @photo.comments.each do |comment| %>
  <%= form_for(comment, url: photo_comment_cflags_path(@photo, comment)) do |f| %>
    <%= f.hidden_field :user_id, value: current_user.id %>
    <%= f.submit "Report Inappropiate" %>
  <% end %>
<% end %> 
class CflagsController < ApplicationController
before_action :logged_in_user

def new
end

def create
  @comment = Comment.find(params[:comment_id])
  @cflag = @comment.cflags.build(cflag_params)
    if @cflag.save
      if @comment.cflags_count > 1
        @comment.update_attribute(:approved, false)  
        flash[:success] = "Flag created! Comment ##{@comment.id} has been removed for review. Thank you for your feedback"
        redirect_to :back
      else    
        flash[:success] = "Flag created! Thank you for your feedback"
        redirect_to :back
      end
    else
      redirect_to :back, notice: @cflag.errors.full_messages  
    end    
  end    

  private 
    def cflag_params
      params.require(:cflag).permit(:user_id, :comment_id).merge(user_id: current_user.id)
    end
end
resources :photos do
  resources :comments, only: [:create, :edit, :destroy] do
    resources :cflags, only: :create
  end  
end
    photo_comment_cflags GET        /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#index
                         POST       /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#create
 new_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/new(.:format)      cflags#new
edit_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id/edit(.:format) cflags#edit
     photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#show
                         PATCH      /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         PUT        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         DELETE     /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#destroy
def show
  @photo = Photo.approved.find(params[:id])
end
def create
   @photo = Photo.find(params[:photo_id])
   @comment = @photo.comments.build(comment_params)
   @comment.save
   respond_to do |format|
     format.html { redirect_to :back }
     format.js 
   end 
end   
class Cflag < ActiveRecord::Base
  belongs_to :comment, counter_cache: true
  belongs_to :user, counter_cache: true
  validates :user_id, presence: true 
  validates :comment_id, presence: true
  validates :user_id, uniqueness: { 
    scope: [:comment_id],
    message: 'You can only flag a comment once. Thank you for your feedback.'
  }
  default_scope -> { order(created_at: :desc) }
end
create_table "cflags", force: :cascade do |t|
  t.integer  "comment_id"
  t.integer  "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "cflags", ["comment_id"], name: "index_cflags_on_comment_id"
add_index "cflags", ["user_id"], name: "index_cflags_on_user_id"
Cflag模型:

# photos/show.html.erb

<% @photo.comments.each do |comment| %>
  <%= form_for(comment, url: photo_comment_cflags_path(@photo, comment)) do |f| %>
    <%= f.hidden_field :user_id, value: current_user.id %>
    <%= f.submit "Report Inappropiate" %>
  <% end %>
<% end %> 
class CflagsController < ApplicationController
before_action :logged_in_user

def new
end

def create
  @comment = Comment.find(params[:comment_id])
  @cflag = @comment.cflags.build(cflag_params)
    if @cflag.save
      if @comment.cflags_count > 1
        @comment.update_attribute(:approved, false)  
        flash[:success] = "Flag created! Comment ##{@comment.id} has been removed for review. Thank you for your feedback"
        redirect_to :back
      else    
        flash[:success] = "Flag created! Thank you for your feedback"
        redirect_to :back
      end
    else
      redirect_to :back, notice: @cflag.errors.full_messages  
    end    
  end    

  private 
    def cflag_params
      params.require(:cflag).permit(:user_id, :comment_id).merge(user_id: current_user.id)
    end
end
resources :photos do
  resources :comments, only: [:create, :edit, :destroy] do
    resources :cflags, only: :create
  end  
end
    photo_comment_cflags GET        /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#index
                         POST       /photos/:photo_id/comments/:comment_id/cflags(.:format)          cflags#create
 new_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/new(.:format)      cflags#new
edit_photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id/edit(.:format) cflags#edit
     photo_comment_cflag GET        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#show
                         PATCH      /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         PUT        /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#update
                         DELETE     /photos/:photo_id/comments/:comment_id/cflags/:id(.:format)      cflags#destroy
def show
  @photo = Photo.approved.find(params[:id])
end
def create
   @photo = Photo.find(params[:photo_id])
   @comment = @photo.comments.build(comment_params)
   @comment.save
   respond_to do |format|
     format.html { redirect_to :back }
     format.js 
   end 
end   
class Cflag < ActiveRecord::Base
  belongs_to :comment, counter_cache: true
  belongs_to :user, counter_cache: true
  validates :user_id, presence: true 
  validates :comment_id, presence: true
  validates :user_id, uniqueness: { 
    scope: [:comment_id],
    message: 'You can only flag a comment once. Thank you for your feedback.'
  }
  default_scope -> { order(created_at: :desc) }
end
create_table "cflags", force: :cascade do |t|
  t.integer  "comment_id"
  t.integer  "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "cflags", ["comment_id"], name: "index_cflags_on_comment_id"
add_index "cflags", ["user_id"], name: "index_cflags_on_user_id"
Heroku控制台中的

p = Photo.find(100) 
p.comments = => #<ActiveRecord::Associations::CollectionProxy [#<Comment id: 309, content: "hi", photo_id: 100, user_id: 1, created_at: "2016-07-24 04:43:17", updated_at: "2016-07-24 04:43:17", approved: true, cflags_count: nil>
p=Photo.find(100)

p、 comments==>#您的第一个参数是array,请尝试以下操作:

<%= form_for(comment, url: photo_comment_cflags_path(@photo, comment)) do |f| %>

根据
方法的表单_,预期参数为
(记录,选项={},&block)

form_for(记录、选项={}、&block)public

创建允许用户创建或更新属性的表单 特定模型对象的

根据具体情况,该方法可采用几种稍有不同的方法 您希望在多大程度上依赖Rails从 对表单的构造方式进行建模。对于常规模型对象, 可以通过传递字符串或符号的
form\u来创建表单
代表我们关注的对象:

因此,您可能希望删除在
方法的表单_中插入的额外的[],它应该如下所示:

<% @photo.comments.each do |comment| %>
  <%= form_for(Cflag.new, url: photo_comment_cflags_path(@photo, comment)) do |f| %>
    <%= f.hidden_field :user_id, value: current_user.id %>
    <%= f.submit "Report Inappropiate" %>
  <% end %>
<% end %> 


我建议您这样尝试,看看它是否解决了您当前的问题。

将表单操作更改为此, 已更新

<% if @photo.comments.any? %>
   <% @photo.comments.each do |comment| %>     
     # you do not have to use comment in form_for, because this form is for creating cflag
     <%= form_for(:cflag, url: photo_comment_cflags_path(@photo, comment), method: "post") do |f| %> 
          <%= f.hidden_field :user_id, value: current_user.id %> 
          <%= f.submit "Report Inappropiate" %> 
     <% end %> 
   <% end %> 
<% end %>

#您不必在表单_中使用注释,因为此表单用于创建cflag

我得到了以下错误代码
ActionView::Template::error(没有路由匹配{:action=>“index”,:comment\u id=>nil,:controller=>“cflags”,:photo\u id=>“100”}缺少必需的键:[:comment\u id]):
@TimmyVonHeiss,我已经更新了我的答案。从表单中,您需要一个新的
Cflag
而不是一个注释,对吗?我仍然得到相同的错误:
ActionView::Template::error(没有路由匹配{:action=>“index”,:comment\u id=>nil,:controller=>“cflags”,:photo\u id=>“100”}缺少所需的键:[:comment\u id]):
您的请求似乎仍由
索引操作处理,而不是此处的
创建操作处理。虽然这不是必需的,但您是否可以尝试将表单方法强制为
:post
,并查看它是否解决了此问题<代码>
否,这是相同的错误消息。我很困惑。当我有额外的
[]
时,我得到的初始错误消息以_for的形式显示了错误消息中的正确url->
{:url=>“/photos/100/comments/309/cflags”}
我得到以下错误代码
ActionView::Template::error(没有与{:action=>“index”,:comment\u id=>nil,:controller=>“cflags”,:photo_id=>“100”}缺少必需的键:[:comment_id]):
Hi,如果在显示页面中已经报告了注释,会发生什么情况?我还没有获得要加载表单的页面,但是如果它确实加载并且已经存在cflag,那么它将触发:
否则重定向到:back,注意:@cflag.errors.full\u messages
因为模型中的唯一性作用域:
验证:user\u id,唯一性:{scope:[:comment\u id],
到目前为止,您使用的是index操作而不是create操作,因为photo\u comment\u cflags代表index操作(注意额外的s改变了整个含义)。我收到以下错误:
ActionView::Template::error(未定义的方法photo\u comment\u cflag\u path
。但是,将其更改为
photo\u comment\u cflags\u path
可以使其工作。我已将cflag路由设置为
仅限:create
。这是令人惊讶的,因为我使用相同的代码尝试了cflag.new和@cflag。我猜
:cflag
实际上就是代码工作与不工作之间的区别ng.你能在我的代码中提到的url前面加上
new\u
吗?实际上现在测试和Cflag.new和:Cflag都能工作。要继续测试以隔离允许此工作的特定代码。当我将路由更改为
new\u photo\u comment\u Cflag\u path
时,我得到以下错误:
ActionView::Template::错误(未定义的方法
new\u photo\u comment\u cflag\u path'`您可以在路由中添加:new method,现在它只接受:create。