我正在为我的Rails项目编写一些测试。我已经围绕多态关联编写了一些测试,为此我已经定义了一个fixture。但是,当我尝试访问该fixture上的多态关联字段时,它会返回nil
。
奇怪的是,虽然字段本身是nil
,但描述它的_id
和_type
字段却不是。{/ p>
这是模型:
class Comment < ActiveRecord::Base
default_scope { where(is_deleted: false) }
belongs_to :post, :polymorphic => true
belongs_to :user
end
(如果不明显,post
关联是多态的。)
这是我试图测试的控制器中的操作:
class CommentsController < ApplicationController
# ...
def update
if @comment.update comment_params
puts @comment.post.nil?
puts @comment.post_id.nil?
puts @comment.post_type.nil?
if @comment.post_type == 'Question'
redirect_to url_for(:controller => :questions, :action => :show, :id => @comment.post.id)
else
redirect_to url_for(:controller => :questions, :action => :show, :id => @comment.post.question.id)
end
else
flash[:error] = "Comment failed to update."
if @comment.post_type == 'Question'
redirect_to url_for(:controller => :questions, :action => :show, :id => @comment.post.id)
else
redirect_to url_for(:controller => :questions, :action => :show, :id => @comment.post.question.id)
end
end
end
private
def comment_params
params.require(:comment).permit(:content, :post_type, :post_id)
end
# ...
end
测试本身如下:
test "should update existing comment" do
sign_in users(:standard_user)
patch :update, :id => comments(:one).id, :comment => { :content => "ABCDEF GHIJKL MNOPQR STUVWX YZ" }
assert_not_nil assigns(:comment)
assert_not_nil assigns(:comment).post
assert_response(302)
end
最后,现有评论(comments(:one)
)的夹具是:
one:
user: standard_user
post: one (Answer)
content: ABCDEF GHIJKL MNOPQR
standard_user
用户夹具和one
答案夹具都已正确定义。
运行测试会给我这个错误:
2) Error:
CommentsControllerTest#test_should_update_existing_comment:
NoMethodError: undefined method `question' for nil:NilClass
app/controllers/comments_controller.rb:50:in `update'
test/controllers/comments_controller_test.rb:16:in `block in <class:CommentsControllerTest>'
update
操作输出true \n false \n false
顶部附近的三条日志行 - 即post
字段为nil
,但post_id
和{ {1}}不是。
这是为什么?我该怎么办才能修复它?我的灯具YAML中没有定义ID字段,我不想指定ID(除非可以使用ERB完成)。
这是评论所依赖的全部答案夹具:
post_type
反过来又取决于这个问题夹具:
one:
body: ABCDEF GHIJKL MNOPQR STUVWX YZ ABCDEF GHIJKL MNOPQR STUVWX YZ
score: 0
question: one
user: standard_user
two:
body: ABCDEF GHIJKL MNOPQR STUVWX YZ ABCDEF GHIJKL MNOPQR STUVWX YZ
score: 0
question: one
user: editor
似乎这个问题是由于评论测试发生时数据库中没有Answer fixtures(因此对one:
title: ABCDEF GHIJKL MNOPQR STUVWX YZ
body: ABCDEF GHIJKL MNOPQR STUVWX YZ ABCDEF GHIJKL MNOPQR STUVWX YZ
tags:
- ABCDEF
- GHIJKL
- MNOPQR
score: 0
user: standard_user
的调用返回nil,@comment.post
或@comment.post.question
加注一个@comment.post.id
)。但是,测试助手文件会调用NoMethodError
,因此我不明白为什么这些灯具没有加载。
答案 0 :(得分:1)
当ActiveRecord无法找到多态关联时会发生这种情况。
即使post_id
和post_type
包含值,但找不到ID Answer
的{{1}},但只有当您comment.post_id
时才会返回nil
致电comment.post
。
你可以粘贴你的answers.yml
灯具吗?我想你可能会不小心把它放进去。
编辑:
我在你的项目中发现了这个bug。您没有在答案和评论表中添加is_deleted的默认值,因此您无法找到正确的记录,因为它们的is_deleted实际上是NULL。我的建议是:永远不要使用default_scope,你总能得到另一个更好的解决方案。