一个has_many Bs,其中B没有主键

Ash*_*she 5 activerecord ruby-on-rails

我有模特A和B; 一个has_many B,B属于一个A.到目前为止,很好 - 除了,我指定B没有主键.我不打算修改或删除单独的B行,并且我希望它们有数百万到数十亿,因此省略主键将非常方便,在空间方面.

创建B表的迁移如下所示:

class CreateBs < ActiveRecord::Migration
  def change
    create_table :bs, {:id => false} do |t|
      # … rest of fields …
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

不幸的是,ActiveRecord不同意; 试图创建一个A(这是正确的!)导致:

1.9.3p194 :001 > A.create!
   (0.3ms)  BEGIN
   (0.1ms)  ROLLBACK
ActiveRecord::UnknownPrimaryKey: ActiveRecord::UnknownPrimaryKey
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/reflection.rb:366:in `primary_key'
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/reflection.rb:216:in `association_primary_key'
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/has_many_association.rb:104:in `foreign_key_present?'
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/association.rb:165:in `find_target?'
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/collection_association.rb:332:in `load_target'
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/collection_proxy.rb:44:in `load_target'
…
Run Code Online (Sandbox Code Playgroud)

如果你发现异常,它的message状态:

"Unknown primary key for table bs in model B." 
Run Code Online (Sandbox Code Playgroud)

(这是因为B没有主键.)

我想不要这个问题!有什么办法吗?

Ash*_*she 3

罪魁祸首原来是问题\xe2\x80\x94当然\xe2\x80\x94中缺失的一个细节,以及我的工作记忆中缺失的一个细节:

\n\n
class A < ActiveRecord::Base\n  has_many :bs\n\n  validates :bs, :presence => true\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

尽管我当时没有想到这一点,但在许多其他验证中,有 \xe2\x80\x94\xe2\x80\x94a 验证bs. 如果你真的仔细地看完整的回溯\xe2\x80\x94,我“有帮助”足以在我原来的问题中截断,你会看到:

\n\n
ActiveRecord::UnknownPrimaryKey: ActiveRecord::UnknownPrimaryKey\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/reflection.rb:366:in `primary_key\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/reflection.rb:216:in `association_primary_key\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/has_many_association.rb:104:in `foreign_key_present?\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/association.rb:165:in `find_target?\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/collection_association.rb:332:in `load_target\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/collection_proxy.rb:44:in `load_target\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.8/lib/active_record/associations/collection_proxy.rb:87:in `method_missing\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.8/lib/active_model/errors.rb:255:in `block in add_on_blank\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.8/lib/active_model/errors.rb:253:in `each\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.8/lib/active_model/errors.rb:253:in `add_on_blank\'\n        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.8/lib/active_model/validations/presence.rb:8:in `validate\'\n-------------------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^\n
Run Code Online (Sandbox Code Playgroud)\n\n

错误发生在active_model/validations/presence.rb!消除这个限制足以让我们继续前进。它无法找到验证的目标,因为它尝试使用主键来执行此操作,因此失败了。

\n