'comments_path' 中的未定义方法使用 "Commentable" form_for 多态关联
Undefined Method in 'comments_path' using "Commentable" form_for Polymorphic association
我收到 "undefined method 'comments_path' for..." 错误
app/views/comments/_form.html.erb(第 1 行)中的这段代码。
我最近尝试在我正在构建的网站上通过多态关联实现可嵌套评论;但是,我 运行 遇到了一个不允许我继续前进的问题。
我正在尝试在 'commentable' 模型(即本例中的博客)上实现嵌套评论,然后在单击显示时显示所有嵌套评论,个人可以在博客上发表评论或者在不离开页面的情况下回复评论(并因此导致嵌套评论)。
我已经包含了一些其他文件来显示设置,但如果我遗漏了一个必要的文件,请告诉我,我会及时添加。任何帮助深表感谢。我被难住了好几个小时,我确信这很简单。
<%= form_for [@commentable, @comment] do |f| %>
<%= f.hidden_field :parent_id %></br>
<%= f.label :content, "New Comment" %></br>
<%= f.text_area :body, :rows => 4 %></br>
<%= f.submit "Submit Comment" %>
<% end %>
app/views/blogs/show.html.erb
<div class="content">
<div class="large-9 columns" role="content">
<h2>Comments</h2>
<div id="comments">
<%= nested_comments @comments %>
<%= render "comments/form" %>
</div>
</div>
</div>
app/controllers/comments_controller
class CommentsController < ApplicationController
def new
@parent_id = params.delete(:parent_id)
@commentable = find_commentable
@comment = Comment.new( :parent_id => @parent_id,
:commentable_id => @commentable.id,
:commentable_type => @commentable.class.to_s)
end
def create
@commentable = find_commentable
@comment = @commentable.comments.build(params[:comment])
if @comment.save
flash[:notice] = "Successfully created comment."
redirect_to @commentable
else
flash[:error] = "Error adding comment."
end
end
private
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return .classify.constantize.find(value)
end
end
nil
end
def comment_params
params.require(:comment).permit(:parent_id, :body, :commentable_type, :commentable_id)
end
end
app/controller/blogs_controller.rb
class BlogsController < ApplicationController
before_filter :authenticate, :except => [ :index, :show ]
before_action :set_blog, only: [:show, :edit, :update, :destroy]
include MyModules::Commentable
# GET /blogs
# GET /blogs.json
def index
@blogs = Blog.all.order('created_at DESC')
respond_to do |format|
format.html
format.json
format.atom
end
end
# GET /blogs/1
# GET /blogs/1.json
def show
@blog = Blog.find(params[:id])
end
# GET /blogs/new
def new
@blog = Blog.new
end
# GET /blogs/1/edit
def edit
@blog = Blog.find(params[:id])
end
# POST /blogs
# POST /blogs.json
def create
@blog = Blog.new(blog_params)
respond_to do |format|
if @blog.save
flash[:success] = "Blog was sucessfuly created"
format.html { redirect_to @blog }
format.json { render :show, status: :created, location: @blog }
else
format.html { render :new }
format.json { render json: @blog.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /blogs/1
# PATCH/PUT /blogs/1.json
def update
respond_to do |format|
if @blog.update(blog_params)
flash[:success] = "Blog was successfully updated."
format.html { redirect_to @blog }
format.json { render :show, status: :ok, location: @blog }
else
format.html { render :edit }
format.json { render json: @blog.errors, status: :unprocessable_entity }
end
end
end
# DELETE /blogs/1
# DELETE /blogs/1.json
def destroy
@blog.destroy
respond_to do |format|
flash[:success] = "Blog was successfully deleted."
format.html { redirect_to blogs_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_blog
@blog = Blog.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def blog_params
params.require(:blog).permit(:title, :body, :image, :image_cache, :remote_image_url)
end
private
def authenticate
authenticate_or_request_with_http_basic do |name, password|
name == "admin" && password == "runfast"
end
end
end
我的路由文件看起来像这样...
Rails.application.routes.draw do
resources :blogs do
resources :comments
end
resources :applications
resources :reviews
resources :properties
root to: 'blogs#index'
end
博客和评论模型...
class Blog < ActiveRecord::Base
validates_presence_of :body, :title
has_many :comments, :as => :commentable, :dependent => :destroy
mount_uploader :image, ImageUploader
end
class Comment < ActiveRecord::Base
has_ancestry
belongs_to :commentable, :polymorphic => true
validates_presence_of :body
end
最后是 lib/my_modules/commentable.rb
中的可注释模块
require 'active_support/concern'
module MyModules::Commentable
extend ActiveSupport::Concern
included do
before_filter :comments, :only => [:show]
end
def comments
@Commentable = find_commentable
@comments = @Commentable.comments.arrange(:order => :created_at)
@comment = Comment.new
end
private
def find_commentable
return params[:controller].singularize.classify.constantize.find(params[:id])
end
end
@博客
#<Blog id: 8, title: "New Blog Post about Databases.... Again", body: "RDM, the database management system, was designed ...", created_at: "2015-03-01 22:28:07", updated_at: "2015-03-03 00:11:07", image: "IMG_2210.JPG">
@commentable
#<Blog id: 8, title: "New Blog Post about Databases.... Again", body: "RDM, the database management system, was designed ...", created_at: "2015-03-01 22:28:07", updated_at: "2015-03-03 00:11:07", image: "IMG_2210.JPG">
app/helpers/comments_helper.rb
module CommentsHelper
def nested_comments(comments)
comments.map do |comment, sub_comments|
content_tag(:div, render(comment), :class => "media")
end.join.html_safe
end
end
@_params 实例变量更好的错误
{"utf8"=>"✓", "authenticity_token"=>"OH2tDdI5Kp54hf5J78wXHe//Zsu+0jyeXuG27v1REqjdAec7yBdlrVPLTZKEbLZxgR2L7rGwUwz5BlGTnPcLWg==", "comment"=>{"parent_id"=>"", "body"=>"Hello!\r\n"}, "commit"=>"Submit Comment", "controller"=>"comments", "action"=>"create", "blog_id"=>"8"}
您在此视图中遇到错误:app/views/blogs/show.html.erb
。
此视图的数据已在 blogs#show
中准备好。所以在你看来,你应该有 <%= form_for [@blog, @comment] do |f| %>
,因为你设置了 @blog
,而不是 @commentable
。
你也应该这样做@comment = Comment.new
。不确定你在哪里设置这个...
在您看来 <% raise @commentable.inspect %>
(app/views/blogs/show.html.erb)。如果它为零,那么这就是您收到错误的原因。
我收到 "undefined method 'comments_path' for..." 错误 app/views/comments/_form.html.erb(第 1 行)中的这段代码。
我最近尝试在我正在构建的网站上通过多态关联实现可嵌套评论;但是,我 运行 遇到了一个不允许我继续前进的问题。
我正在尝试在 'commentable' 模型(即本例中的博客)上实现嵌套评论,然后在单击显示时显示所有嵌套评论,个人可以在博客上发表评论或者在不离开页面的情况下回复评论(并因此导致嵌套评论)。
我已经包含了一些其他文件来显示设置,但如果我遗漏了一个必要的文件,请告诉我,我会及时添加。任何帮助深表感谢。我被难住了好几个小时,我确信这很简单。
<%= form_for [@commentable, @comment] do |f| %>
<%= f.hidden_field :parent_id %></br>
<%= f.label :content, "New Comment" %></br>
<%= f.text_area :body, :rows => 4 %></br>
<%= f.submit "Submit Comment" %>
<% end %>
app/views/blogs/show.html.erb
<div class="content">
<div class="large-9 columns" role="content">
<h2>Comments</h2>
<div id="comments">
<%= nested_comments @comments %>
<%= render "comments/form" %>
</div>
</div>
</div>
app/controllers/comments_controller
class CommentsController < ApplicationController
def new
@parent_id = params.delete(:parent_id)
@commentable = find_commentable
@comment = Comment.new( :parent_id => @parent_id,
:commentable_id => @commentable.id,
:commentable_type => @commentable.class.to_s)
end
def create
@commentable = find_commentable
@comment = @commentable.comments.build(params[:comment])
if @comment.save
flash[:notice] = "Successfully created comment."
redirect_to @commentable
else
flash[:error] = "Error adding comment."
end
end
private
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return .classify.constantize.find(value)
end
end
nil
end
def comment_params
params.require(:comment).permit(:parent_id, :body, :commentable_type, :commentable_id)
end
end
app/controller/blogs_controller.rb
class BlogsController < ApplicationController
before_filter :authenticate, :except => [ :index, :show ]
before_action :set_blog, only: [:show, :edit, :update, :destroy]
include MyModules::Commentable
# GET /blogs
# GET /blogs.json
def index
@blogs = Blog.all.order('created_at DESC')
respond_to do |format|
format.html
format.json
format.atom
end
end
# GET /blogs/1
# GET /blogs/1.json
def show
@blog = Blog.find(params[:id])
end
# GET /blogs/new
def new
@blog = Blog.new
end
# GET /blogs/1/edit
def edit
@blog = Blog.find(params[:id])
end
# POST /blogs
# POST /blogs.json
def create
@blog = Blog.new(blog_params)
respond_to do |format|
if @blog.save
flash[:success] = "Blog was sucessfuly created"
format.html { redirect_to @blog }
format.json { render :show, status: :created, location: @blog }
else
format.html { render :new }
format.json { render json: @blog.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /blogs/1
# PATCH/PUT /blogs/1.json
def update
respond_to do |format|
if @blog.update(blog_params)
flash[:success] = "Blog was successfully updated."
format.html { redirect_to @blog }
format.json { render :show, status: :ok, location: @blog }
else
format.html { render :edit }
format.json { render json: @blog.errors, status: :unprocessable_entity }
end
end
end
# DELETE /blogs/1
# DELETE /blogs/1.json
def destroy
@blog.destroy
respond_to do |format|
flash[:success] = "Blog was successfully deleted."
format.html { redirect_to blogs_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_blog
@blog = Blog.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def blog_params
params.require(:blog).permit(:title, :body, :image, :image_cache, :remote_image_url)
end
private
def authenticate
authenticate_or_request_with_http_basic do |name, password|
name == "admin" && password == "runfast"
end
end
end
我的路由文件看起来像这样...
Rails.application.routes.draw do
resources :blogs do
resources :comments
end
resources :applications
resources :reviews
resources :properties
root to: 'blogs#index'
end
博客和评论模型...
class Blog < ActiveRecord::Base
validates_presence_of :body, :title
has_many :comments, :as => :commentable, :dependent => :destroy
mount_uploader :image, ImageUploader
end
class Comment < ActiveRecord::Base
has_ancestry
belongs_to :commentable, :polymorphic => true
validates_presence_of :body
end
最后是 lib/my_modules/commentable.rb
中的可注释模块require 'active_support/concern'
module MyModules::Commentable
extend ActiveSupport::Concern
included do
before_filter :comments, :only => [:show]
end
def comments
@Commentable = find_commentable
@comments = @Commentable.comments.arrange(:order => :created_at)
@comment = Comment.new
end
private
def find_commentable
return params[:controller].singularize.classify.constantize.find(params[:id])
end
end
@博客
#<Blog id: 8, title: "New Blog Post about Databases.... Again", body: "RDM, the database management system, was designed ...", created_at: "2015-03-01 22:28:07", updated_at: "2015-03-03 00:11:07", image: "IMG_2210.JPG">
@commentable
#<Blog id: 8, title: "New Blog Post about Databases.... Again", body: "RDM, the database management system, was designed ...", created_at: "2015-03-01 22:28:07", updated_at: "2015-03-03 00:11:07", image: "IMG_2210.JPG">
app/helpers/comments_helper.rb
module CommentsHelper
def nested_comments(comments)
comments.map do |comment, sub_comments|
content_tag(:div, render(comment), :class => "media")
end.join.html_safe
end
end
@_params 实例变量更好的错误
{"utf8"=>"✓", "authenticity_token"=>"OH2tDdI5Kp54hf5J78wXHe//Zsu+0jyeXuG27v1REqjdAec7yBdlrVPLTZKEbLZxgR2L7rGwUwz5BlGTnPcLWg==", "comment"=>{"parent_id"=>"", "body"=>"Hello!\r\n"}, "commit"=>"Submit Comment", "controller"=>"comments", "action"=>"create", "blog_id"=>"8"}
您在此视图中遇到错误:app/views/blogs/show.html.erb
。
此视图的数据已在 blogs#show
中准备好。所以在你看来,你应该有 <%= form_for [@blog, @comment] do |f| %>
,因为你设置了 @blog
,而不是 @commentable
。
你也应该这样做@comment = Comment.new
。不确定你在哪里设置这个...
在您看来 <% raise @commentable.inspect %>
(app/views/blogs/show.html.erb)。如果它为零,那么这就是您收到错误的原因。