简体   繁体   中英

Ruby on Rails renamed foreign key

I'm trying to create a model for a comic book which has 1 writer and 1 artist. These are both instances of a Person. However how do I show this in my migration?

class CreateComics < ActiveRecord::Migration
   def self.up
     create_table :comics do |t|
       t.column :name, :string      
       t.column :writer_id, :integer, :null => false
       t.column :artist_id, :integer, :null => false
     end
   end
...

How do I say :writer_id should map to :person_id or is this kind of renaming frowned upon?

You create the mapping in your model class using the class_name and foreign_key option.

belongs_to :writer, :class_name => "Person", :foreign_key => "writer_id"
belongs_to :artist, :class_name => "Person", :foreign_key => "artist_id"

The migration has no knowledge of how you intend to use the tables defined within it. All that information goes in the models.

In short your migration is fine for what you've described will be done. But you need to flesh out the models to define the associations you're thinking of.

class Comic < ActiveRecord::Base
  belongs_to :writer, :class_name => "Person"
  belongs_to :artist, :class_name => "Person"
end

This allows you to reference the Writer and Artist from a Comic. However, you will probably want to reciprocate the association so that you can easily fetch a comic from a person based on their role in it's production.

class Person < ActiveRecord::Base
  has_many :comics_as_writer, :class_name => "Comic", :foreign_key => :writer_id
  has_many :comics_as_artist, :class_name => "Comic", :foreign_key => :artist_id

  # some times you don't care what a person did for a comic,
  # you just want to know what they worked on.
  has_many :comics, :finder_sql => "SELECT comics.* FROM comics, people WHERE " +
     "`comics`.`writer_id` = `people`.`id` OR " +
     " `comics`.`artist_id` = `people`.`id`"
end

With these relationships defined the following is possible:

@comic.artist # => Person with id matching comics.artist_id
@comic.writer # => Person with id matching comics.writer_id

@person.comics_as_writer # => Array of comics where @person.id matches comics.writer_id
@person.comics_as_artist # => Array of comics where @person.id matches comics.artist_id

@person.comics # => Array of comics where @person.id matches comics.writer_id or comics.artist_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM