我只是把它扔在那里,因为我真的无法弄清楚。例如,当我调用
user.articles.create! { title: 'blah' }
时,会返回 nil,但会创建对象。我以前从未见过这样的东西,想知道其他人是否见过?
我尝试过 Rails 3.2.13 和 3.2.12,它们都做了同样的事情。
编辑
在活动记录中创建和创建!最终以这种方法结束,该方法应该返回记录或引发异常。
def create_record(attributes, options, raise = false, &block)
unless owner.persisted?
raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
end
if attributes.is_a?(Array)
attributes.collect { |attr| create_record(attr, options, raise, &block) }
else
transaction do
add_to_target(build_record(attributes, options)) do |record|
yield(record) if block_given?
insert_record(record, true, raise)
end
end
end
end
如果我没记错的话工厂女孩通过预定义的工厂模仿您正在处理的实际对象。因此,当调用工厂时,
User#articles
可能不会返回您认为的内容。
改变
user.articles.create! { title: 'blah' }
到
create(:article, user: user, title: 'blah')
应通过 Factory Girl 的界面强制执行关联。
我有同样的症状,这个问题是我能找到的唯一相关的命中。我会将我的解决方案加入其中,以防对其他人有帮助。
该代码在现实生活中有效,仅在
rspec
下失败。我所做的所有故障排除都毫无意义,表明 create!
已损坏,我从来不相信这一点。
事实证明,我在嘲笑
create!
,所以它从未被调用。在我的模拟中添加 .and_call_original
解决了问题。
我的模型是这样的:(不是真的......但与这个答案兼容)
class Flight < ApplicationRecord
has_many :seats
def create_seats(seat_count)
seat_count.times { Seat.create!(flight: self) }
seats.each(&:raise_seatback_and_lock_tray)
end
我的测试是:
it 'creates enough empty seats' do
expect(Seat).to receive(:create!).twice
flight.create_seats(2)
end
达到预期(手动确认),但出现错误:
NoMethodError:
undefined method `raise_seatback_and_lock_tray=' for nil:NilClass
更改我的模拟以允许实际调用
create!
解决了问题:
it 'creates enough empty seats' do
expect(Seat).to receive(:create!).twice.and_call_original
flight.create_seats(2)
end
现在已经过去了:
creates enough empty seats
1 example, 0 failures