J'aimerais connaître la manière "correcte" d'aborder l'ajout d'une relation entre deux existantes classes dans Rails 3.
Compte tenu des modèles existants: Clown & Rabbit
Je voudrais ajouter une référence (appartient_to) de Lapin à Clown. Je commence par essayer de générer une migration:
Rails g migration AddClownToRabbits clown:reference
ce qui me donne une migration qui ressemble à:
class AddClownToRabbits < ActiveRecord::Migration
def self.up
add_column :rabbits, :clown, :reference
end
def self.down
remove_column :rabbits, :clown
end
end
Après rake db:migrate
sur cette migration, j'examine development.db de SQLite3 et vois une nouvelle colonne: "clown" reference
Je suppose que je m'attendais à un "clown_id" integer
colonne et une migration qui ressemblait à:
class AddClownToRabbits < ActiveRecord::Migration
def self.up
add_column :rabbits, :clown_id
end
def self.down
remove_column :rabbits, :clown_id
end
end
J'en suis sûr: la référence est censée être équivalente à "t.references: clown" mais je ne trouve pas la documentation (grosse surprise). L'API dit add_column: Instantiates a new column for the table. The type parameter is normally one of the migrations native types, which is one of the following: :primary_key, :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean.
... sans référence à: référence.
Une fois que vous avez défini appartient_to dans Rabbit et has_many dans Clown, vous pouvez effectuer une migration avec:
add_column :rabbit, :clown_id, :integer
Si vous utilisez Edge Rails (4.0), vous pouvez utiliser:
Rails generate migration AddAddressRefToContacts address:references
Comme vous pouvez le voir par docs .
Je ne sais pas d'où vous avez cette idée, mais il n'y a pas (et n'a jamais été) une telle syntaxe pour faire ce que vous voulez avec add_column
. Pour obtenir le comportement que vous souhaitez, vous devez faire t.refences :clown
, Comme vous l'avez indiqué. En arrière-plan, cela appellera: @base.add_column(@table_name, "#{col}_id", :integer, options)
.
Voir ici .
ÉDITER:
Je pense que je peux voir la source de votre confusion. Vous avez vu la méthode appeler t.reference
Et supposé qu'il s'agissait d'un type de données car des appels tels que t.integer
Et t.string
Existent, et ce sont des types de données. C'est faux. La référence n'est pas un type de données, c'est simplement le nom d'une méthode, semblable à t.rename
.