25

もう 1 つの基本的な Rails の質問:

特定のデータ型の 2 つの異なるレコードへの参照を含める必要があるデータベース テーブルがあります。

仮定の例: ビデオ ゲームのデータベースを作成しています。「会社」のテーブルがあります。「ビデオゲーム」エントリごとに、正確に 1 人の開発者と正確に 1 つのパブリッシャーが必要です。

1つの会社を持ちたい場合は、次のようにすることができます。

script/generate Videogame company:references

しかし、私は両方の会社を持つ必要があります。指定されたデータ型は正確に 2 つしか存在できず、それらを区別する必要があるため、結合テーブルは使用したくありません。

答えはかなり明白なはずですが、インターネット上のどこにも見つかりません。

4

3 に答える 3

49

少し整理するために、移行では次のことも実行できます。

create_table :videogames do |t|
  t.belongs_to :developer
  t.belongs_to :publisher
end

また、キーdeveloper_idとpublisher_idを呼び出しているので、モデルはおそらく次のようになります。

belongs_to :developer, :class_name => "Company"
belongs_to :publisher, :class_name => "Company"

これは大きな問題ではありませんが、追加の引数との関連付けの数が増えると、明確さが低下するため、可能な限りデフォルトを使用することをお勧めします。

于 2009-01-06T18:37:32.493 に答える
9

script/generateでこれを行う方法がわかりません。

根底にあるアイデアは、とにかくスクリプト/生成を使用せずに表示する方が簡単です。会社のテーブル/モデルへの外部キーを保持する2つのフィールドがビデオゲームのテーブル/モデルに必要です。

コードがどのようになるかをお見せしますが、テストしていないので、間違っている可能性があります。

移行ファイルには次のものがあります。

create_table :videogames do |t|
  # all your other fields
  t.int :developer_id
  t.int :publisher_id
end

次に、モデルで:

belongs_to :developer, class_name: "Company", foreign_key: "developer_id"
belongs_to :publisher, class_name: "Company", foreign_key: "publisher_id"

また、2つの会社を区別する必要があることにも言及しました。これは、それをチェックするモデルの検証で処理できますdeveloper_id != publisher_id

于 2009-01-06T17:53:12.520 に答える
2

特定の会社タイプに固有のメソッドまたは検証が必要な場合は、会社モデルをサブクラス化できます。これは、単一テーブル継承と呼ばれる手法を採用しています。詳細については、この記事を参照してください: http://wiki.rubyonrails.org/rails/pages/singletableinheritance

次に、次のようになります。

#db/migrate/###_create_companies
class CreateCompanies < ActiveRecord::Migration
  def self.up
    create_table :companies do |t|
      t.string :type  # required so rails know what type of company a record is
      t.timestamps
    end
  end

  def self.down
    drop_table :companies
  end
end

#db/migrate/###_create_videogames
class CreateVideogames < ActiveRecord::Migration
  create_table :videogames do |t|
    t.belongs_to :developer
    t.belongs_to :publisher
  end    

  def self.down
    drop_table :videogames
  end
end

#app/models/company.rb
class Company < ActiveRecord::Base 
  has_many :videogames
  common validations and methods
end

#app/models/developer.rb
class Developer < Company
  developer specific code
end

#app/models/publisher.rb
class Publisher < Company
  publisher specific code
end

#app/models/videogame.rb
class Videogame < ActiveRecord::Base 
  belongs_to :developer, :publisher
end

その結果、Company、Developer、および Publisher モデルを使用することになります。

 Company.find(:all)
 Developer.find(:all)
 Publisher.find(:all)
于 2009-01-07T06:42:01.110 に答える