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

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

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

class CreateBs  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' … 

如果您捕获exception,则其message指出:

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

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

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

罪魁祸首原来是一个细节遗漏的问题 – 当然 – 并且从我的工作记忆中遗漏:

 class A < ActiveRecord::Base has_many :bs validates :bs, :presence => true end 

虽然我当时没有想到它,但还有许多其他validation – 对bs存在的validation。 如果你在完全回溯中眯着眼睛 – 我有“帮助”足以在我的原始问题中截断,你会看到:

 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发生错误! 删除此约束足以让我们前进。 它无法找到validation的目标,因为它尝试使用主键来执行此操作,因此失败了。

嗯,这很奇怪。 出于某种原因,鉴于您发布的信息,我不能在我的问题上复制问题。 我创建了一个新项目,创建了一个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?