[英]Rails association.create and association.create! returns nil
I'm just throwing this out there because I really can't figure this out.我只是把它扔在那里,因为我真的想不通。 When I call for instance
user.articles.create! { title: 'blah' }
当我调用例如
user.articles.create! { title: 'blah' }
user.articles.create! { title: 'blah' }
nil is returned but the object is created. user.articles.create! { title: 'blah' }
返回 nil 但对象已创建。 I've not seen anything like this before and was wondering if someone else has?我以前从未见过这样的东西,想知道其他人是否见过?
I've tried rails 3.2.13 and 3.2.12 and they both do the same thing.我试过 Rails 3.2.13 和 3.2.12,它们都做同样的事情。
EDIT编辑
In active record both create and create!在活动记录中创建和创建! ends up IN THIS METHOD that is supposed to return the record or throw an exception.
最终在这个应该返回记录或抛出异常的方法中。
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
If I'm not mistaken Factory Girl mimic the actual object you're dealing with through your predefined factory.如果我没记错的话, Factory Girl会通过预定义的工厂模拟您正在处理的实际对象。 Therefor
User#articles
might not return what you think it is when called on a factory.因此
User#articles
在调用工厂时可能不会返回您认为的内容。
Changing改变
user.articles.create! { title: 'blah' }
to到
create(:article, user: user, title: 'blah')
should enforce the association through Factory Girl's interface.应该通过 Factory Girl 的界面强制关联。
I believe there is something going on with your attr_accessible
or attr_accessor
in your Article
class.我相信你的
Article
类中的attr_accessible
或attr_accessor
有问题。 I you might have not included the user_id
or something else...我你可能没有包括
user_id
或其他东西......
There is also a similar question here: rails Model.create(:attr=>"value") returns model with uninitialized fields这里也有一个类似的问题: rails Model.create(:attr=>"value") 返回带有未初始化字段的模型
I had the same symptom, and this question is the only relevant hit that I could find.我有同样的症状,这个问题是我能找到的唯一相关问题。 I'll throw my solution into the mix in case it helps anyone else.
我会把我的解决方案混合在一起,以防它对其他人有帮助。
The code worked in real life, and only failed under rspec
.该代码在现实生活中有效,仅在
rspec
下失败。 All the troubleshooting I did made no sense, pointing to create!
我做的所有故障排除都没有意义,指点
create!
being broken, which I never believed.被打破了,我从来不相信。
As it turns out, I was mocking create!
事实证明,我在嘲笑
create!
so it never got called.所以它从未被调用。 Adding
.and_call_original
to my mock solved the problem.将
.and_call_original
添加到我的模拟中解决了这个问题。
My model was something like this: (not really...but compatible with this answer)我的模型是这样的:(不是真的......但与这个答案兼容)
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
And my test was:我的测试是:
it 'creates enough empty seats' do
expect(LicenseFile).to receive(:create!).twice
flight.create_seats(2)
end
The expectation was met (confirmed manually), but an error was raised:达到了预期(手动确认),但出现错误:
NoMethodError:
undefined method `raise_seatback_and_lock_tray=' for nil:NilClass
Changing my mock to allow create!
更改我的模拟以允许
create!
to actually be called solved the problem:实际上被称为解决了问题:
it 'creates a LicenseFile for each destination rule' do
expect(LicenseFile).to receive(:create!).twice.and_call_original
flight.create_seats(2)
end
This now passed:现在通过了:
creates enough empty seats
1 example, 0 failures
If you are expecting the object to be returned use如果您希望返回对象,请使用
user.articles.create { title: 'blah' }
Why some methods have bang (!), you can read this topic Why are exclamation marks used in Ruby methods?为什么有些方法有 bang (!),你可以阅读这个主题为什么 Ruby 方法中使用感叹号?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.