简体   繁体   English

Rails association.create 和association.create! 返回零

[英]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_accessibleattr_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM