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

时间:2012-08-18 12:56:14

标签: ruby-on-rails activerecord

我有模特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

不幸的是,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'
…

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

"Unknown primary key for table bs in model B." 

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

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

2 个答案:

答案 0 :(得分:3)

罪魁祸首竟然是问题中缺少的一个细节 - 当然 - 并且从我的工作记忆中遗漏:

class A < ActiveRecord::Base
  has_many :bs

  validates :bs, :presence => true
end

虽然我当时一无所知,但还有许多其他验证 - 验证了bs的存在。如果你在完全回溯中眯着眼睛 - 这对于我在原始问题中被截断的“有用”,你会看到:

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'
        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'
        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'
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.8/lib/active_model/errors.rb:253:in `each'
        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'
        from /Users/annelicuss/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.8/lib/active_model/validations/presence.rb:8:in `validate'
-------------------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^

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

答案 1 :(得分:1)

嗯,这很奇怪。出于某种原因,鉴于您发布的信息,我不能在我的问题上复制问题。我创建了一个新项目,创建了一个A模型,后跟一个引用A的B模型,并运行了迁移。我的B表没有主键,只有A的外键,如预期的那样。

我唯一可以建议的是以下

写下你的A模型:

class A < ActiveRecord::Base
  has_many :b, :primary_key=>:myPrimaryKeyFunction # name this function whatever you want, other than :id of course
end

然后,在B模型中,只需创建相应的“myPrimaryKeyFunction”函数。

除此之外,我不确定还有什么建议。您运行的是哪个版本的rails和哪个DB?