nil的未定义方法`yaml':尝试保存重复对象时的NilClass

时间:2012-09-01 22:36:25

标签: ruby-on-rails

我有一个名为Event的Active Record模型对象,它有许多event_things。我希望能够复制事件,以便获得新的id。我正在使用Rails 3.2并且在rails控制台中能够成功调用

event_copy = event.dup
event_copy.save

但是,我还希望复制每个Event的event_things。

copy = event_thing.dup
copy.event_id = event_copy.id
copy.save

但是这给了我这个错误堆栈:

NoMethodError: undefined method `yaml' for nil:NilClass
    from /Users/Ed/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/psych.rb:204:in `dump_stream'
    from /Users/Ed/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/psych/core_ext.rb:35:in `psych_y'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activemodel-3.2.6/lib/active_model/dirty.rb:143:in `attribute_change'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activemodel-3.2.6/lib/active_model/dirty.rb:117:in `block in changes'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activemodel-3.2.6/lib/active_model/dirty.rb:117:in `map'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activemodel-3.2.6/lib/active_model/dirty.rb:117:in `changes'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/attribute_methods/dirty.rb:23:in `save'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/transactions.rb:241:in `block (2 levels) in save'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/transactions.rb:208:in `transaction'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/transactions.rb:241:in `block in save'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/transactions.rb:252:in `rollback_active_record_state!'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/transactions.rb:240:in `save'
    from (irb):18
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.6/lib/rails/commands/console.rb:47:in `start'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.6/lib/rails/commands/console.rb:8:in `start'
    from /Users/Ed/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.6/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'

2 个答案:

答案 0 :(得分:1)

我遇到了与此相同的问题。事实证明,基于this article,有Kernel.y扩展方法阻碍了您。以下是我为解决问题所做的工作:

class Event < ActiveRecord::Base
  # alias the attributes
  alias_attribute :x_pos, :x
  alias_attribute :y_pos, :y

  after_initialize :init

  # after_initialize will still work, with the aliases
  def init
    self.x_pos ||= 0
    self.y_pos ||= 0
  end

  # override Kernel.y
  def y; end

  # override self.y_pos to read out of the :attributes, since we blew away :y
  def y_pos
    attribute['y']
  end
end

执行此操作后,我终于可以使用我的模型而无需重命名y数据库列。

答案 1 :(得分:0)

虽然我通常不提倡大量使用宝石,但如果你需要在复制中保留很多关系,或者发现自己经常进行这些手动复制,请查看deep_clonable

至于您的具体错误,请尝试使用零检查(每次一行)围绕每行代码。我敢肯定,在某些情况下,你最终会看到一个你忽略的零物体。