我在使这些多态关联完全正常工作时遇到了一些麻烦。我遵循了本教程www.railscasts.com/episodes/154-polymorphic-association,但这似乎只有在我发布新帖子时我是路径/控制器/ ID#/注释时才有效。如果我尝试在/ controller / ID#上呈现部分注释表单,则在创建注释时会出现此错误:
undefined method `comments' for #<ActiveSupport::HashWithIndifferentAccess:0x10341b2d0>
我有三种模式:
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, :as => :commentable
end
class Article < ActiveRecord::Base
belongs_to :user
has_many :comments, :as => :commentable
end
这是我对/ articles /#{ID}
的看法<%= @article.title %>
<%= @article.content %>
<%= @article.user.login %>
<%= link_to 'Edit Article', edit_article_path(@article) %>
<h2>Comments</h2>
<%= render "comments/comments" %>
<%= render "comments/comment" %>
这是我的评论部分:
<div class="post_comment">
<%= form_for [@commentable, Comment.new] do |f| %>
<%= f.text_area :content %>
<%= f.submit "Post" %>
<% end %>
</div>
这是我在评论控制器中的创建方法:
def create
@commentable = find_commentable
@comment = @commentable.comments.build(params[:comment])
@comment.user_id = current_user.id
if @comment.save
redirect_to :id => nil
else
flash[:notice] = "something went wrong"
redirect_to @commentable
end
end
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
end
我想我明白这个问题是什么,但不知道如何解决问题。此表单正在寻找@commentable,但如果路径未嵌套,则无法找到@commentable(可能是错误的)。
以下是我的路线:
devise_for :users do
get "login", :to => "devise/sessions#new"
get "register", :to => "devise/registrations#new"
end
resources :posts do
resources :comments
resources :tags
end
resources :articles do
resources :comments
resources :tags
end
resources :users do
resources :articles
resources :comments
resources :tags
resources :posts
end
resources :comments
root :to => "home#index"
end
答案 0 :(得分:2)
你的问题是find_commentable返回params散列本身,因为return语句从未被触发过。
我通过错误消息推断出这一点,因为params.class == ActiveSupport::HashWithIndiffrentAccess
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
end
我会添加类似
的内容def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
raise ActiveRecord:NoRecord.new("Couldn\'t find it captain!")
end
我认为上面的异常类型是正确的,如果没有看到什么Comment.find_by_id(-1)或类似的东西引发。应该是这样的。
我建议引发异常的原因是因为ApplicationController应该捕获这些并在人们开始调整时优雅地处理它们并转到example.com/posts/9001
答案 1 :(得分:0)
devise_for :users do
get "login", :to => "devise/sessions#new"
get "register", :to => "devise/registrations#new"
end
resources :posts do
resources :comments
resources :tags
end
resources :articles do
resources :comments
resources :tags
end
resources :users do
resources :articles
resources :comments
resources :tags
resources :posts
end
#REMOVE IT resources :comments
root :to => "home#index"
end
并添加
def index
@commentable = find_commentable #this
@comments = @commentable.comments
respond_to do |format|
format.html # index.html.erb
format.json { render json: @comments }
end
end