5

モデルAとBがあります。A 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に主キーがないためです。)

この問題は発生させたくありません。方法はありますか?

4

2 に答える 2

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!で発生します この制約を取り除くだけで、私たちはうまくいくことができます。主キーを使用して検証しようとするため、検証のターゲットを見つけることができず、失敗します。

于 2012-08-21T09:04:47.950 に答える
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」関数を作成するだけです。

それ以外に、他に何を提案すべきかわかりません。どのバージョンのレールとどのDBを実行していますか?

于 2012-08-20T21:10:40.737 に答える