如何修复此 sort_by in collection_select 在浏览器中有效但在 Capybara 中出现 returns "comparison of String with nil failed" 错误
How to fix this sort_by in collection_select works in the browser but returns "comparison of String with nil failed" error in Capybara
我一直在尝试为在浏览器中手动工作的表单编写系统测试。
我有一个 Speaker
型号 has_one :individual
。表单字段如下所示:
<fieldset>
<%= form.label :speaker, "Who said it?" %>
<%= form.collection_select :speaker_id, Speaker.all.sort_by(&:full_name), :id, :full_name %>
</fieldset>
Speaker
模型中的自定义 full_name
方法如下所示:
def full_name
if individual
"#{individual.first_name} #{individual.last_name}"
end
end
if individual
条件是一种气味,但没有它,我得到这个错误:
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `first_name' for nil:NilClass
如果我添加 if individual
条件,则错误如下所示:
Minitest::UnexpectedError: ActionView::Template::Error: comparison of String with nil failed
我很困惑,因为我在其他模型中使用类似的模式按 full_name
对集合选择进行排序,但这是唯一在系统测试中引发错误的模式。当我在浏览器中手动测试时,一切都按预期工作。
我也可以在控制台中的 Individual
模型中访问 first_name
last_name
和 full_name
方法,没问题。
这也不会导致错误(我可以使用 :full_name
在浏览器中显示名称,但它不是按字母顺序排列的:
<%= form.collection_select :speaker_id, Speaker.all, :id, :full_name %>
如何修复 Capybara 中的这个错误?或者有没有更好的方法让 return Speaker.all
中的 collection_select 按字母顺序排序?
更新:
我通过不通过 Speaker 模型传递 Quote / Individual 关系来简化这一点。现在,我的 Quote
模型 belongs_to :individual
和 Individual
has_many :quotes
。这也适用于浏览器,但我的系统测试遇到了同样的错误:
<ActionView::Template::Error: undefined method `full_name' for nil:NilClass>
这是因该错误而失败的测试之一...
require "application_system_test_case"
class QuotesTest < ApplicationSystemTestCase
setup do
@contributor = users(:contributor)
@contributor_quote = quotes(:contributor_quote)
@category = categories(:rock_and_roll)
@field = fields(:music)
@topic_one = topics(:recording)
@topic_two = topics(:songwriting)
@individual = individuals(:john_lennon)
@group = groups(:the_beatles)
end
test "visiting the index should be accessible to all" do
visit quotes_path
assert_text @contributor_quote.body
click_on @contributor_quote.body
assert_current_path quote_path(@contributor_quote)
end
end
我的 Individual
模型中有这个方法:
def full_name
"#{first_name} #{last_name}"
end
这是导致失败的视图部分:
Speaker: <%= @quote.individual.full_name %>
如果我包含 save_and_open_page
错误看起来像这样...
我尝试按照 Thomas 的回答建议添加 .strip
,但这无济于事。
同样,唯一的问题是这个系统测试。它在浏览器中运行良好。
在没有实际看到任何测试代码的情况下,无法确定错误的来源,而且我不知道 Capybara 在何处适用。我猜你拥有的是一个 Speaker 模型,它似乎依赖于与之关联的 individual
,但实际上并没有在任何地方强制执行,所以当你在没有关联个体的情况下在测试中创建扬声器实例时,它是没有被标记为无效。如果 Speaker 应该支持没有关联的 individual
那么你的问题是你的 full_name
方法在需要字符串时返回 nil 。要解决这个问题,您可以这样做
def full_name
"#{individual&.first_name} #{individual&.last_name}".strip
end
当 individual
存在时给你全名,不存在时给你一个空字符串
我一直在尝试为在浏览器中手动工作的表单编写系统测试。
我有一个 Speaker
型号 has_one :individual
。表单字段如下所示:
<fieldset>
<%= form.label :speaker, "Who said it?" %>
<%= form.collection_select :speaker_id, Speaker.all.sort_by(&:full_name), :id, :full_name %>
</fieldset>
Speaker
模型中的自定义 full_name
方法如下所示:
def full_name
if individual
"#{individual.first_name} #{individual.last_name}"
end
end
if individual
条件是一种气味,但没有它,我得到这个错误:
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `first_name' for nil:NilClass
如果我添加 if individual
条件,则错误如下所示:
Minitest::UnexpectedError: ActionView::Template::Error: comparison of String with nil failed
我很困惑,因为我在其他模型中使用类似的模式按 full_name
对集合选择进行排序,但这是唯一在系统测试中引发错误的模式。当我在浏览器中手动测试时,一切都按预期工作。
我也可以在控制台中的 Individual
模型中访问 first_name
last_name
和 full_name
方法,没问题。
这也不会导致错误(我可以使用 :full_name
在浏览器中显示名称,但它不是按字母顺序排列的:
<%= form.collection_select :speaker_id, Speaker.all, :id, :full_name %>
如何修复 Capybara 中的这个错误?或者有没有更好的方法让 return Speaker.all
中的 collection_select 按字母顺序排序?
更新:
我通过不通过 Speaker 模型传递 Quote / Individual 关系来简化这一点。现在,我的 Quote
模型 belongs_to :individual
和 Individual
has_many :quotes
。这也适用于浏览器,但我的系统测试遇到了同样的错误:
<ActionView::Template::Error: undefined method `full_name' for nil:NilClass>
这是因该错误而失败的测试之一...
require "application_system_test_case"
class QuotesTest < ApplicationSystemTestCase
setup do
@contributor = users(:contributor)
@contributor_quote = quotes(:contributor_quote)
@category = categories(:rock_and_roll)
@field = fields(:music)
@topic_one = topics(:recording)
@topic_two = topics(:songwriting)
@individual = individuals(:john_lennon)
@group = groups(:the_beatles)
end
test "visiting the index should be accessible to all" do
visit quotes_path
assert_text @contributor_quote.body
click_on @contributor_quote.body
assert_current_path quote_path(@contributor_quote)
end
end
我的 Individual
模型中有这个方法:
def full_name
"#{first_name} #{last_name}"
end
这是导致失败的视图部分:
Speaker: <%= @quote.individual.full_name %>
如果我包含 save_and_open_page
错误看起来像这样...
我尝试按照 Thomas 的回答建议添加 .strip
,但这无济于事。
同样,唯一的问题是这个系统测试。它在浏览器中运行良好。
在没有实际看到任何测试代码的情况下,无法确定错误的来源,而且我不知道 Capybara 在何处适用。我猜你拥有的是一个 Speaker 模型,它似乎依赖于与之关联的 individual
,但实际上并没有在任何地方强制执行,所以当你在没有关联个体的情况下在测试中创建扬声器实例时,它是没有被标记为无效。如果 Speaker 应该支持没有关联的 individual
那么你的问题是你的 full_name
方法在需要字符串时返回 nil 。要解决这个问题,您可以这样做
def full_name
"#{individual&.first_name} #{individual&.last_name}".strip
end
当 individual
存在时给你全名,不存在时给你一个空字符串