Scaffolding ActiveRecord: two columns of the same data type

前端 未结 3 1673
旧时难觅i
旧时难觅i 2020-12-16 11:41

Another basic Rails question:

I have a database table that needs to contain references to exactly two different records of a specific data type.

Hypothetical

相关标签:
3条回答
  • 2020-12-16 11:50

    I have no idea how to do this with script/generate.

    The underlying idea is easier to show without using script/generate anyway. You want two fields in your videogames table/model that hold the foreign keys to the companies table/model.

    I'll show you what I think the code would look like, but I haven't tested it, so I could be wrong.

    Your migration file has:

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

    Then in your model:

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

    You also mention wanting the two companies to be distinct, which you could handle in a validation in the model that checks that developer_id != publisher_id.

    0 讨论(0)
  • 2020-12-16 11:54

    Just to tidy things up a bit, in your migration you can now also do:

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

    And since you're calling the keys developer_id and publisher_id, the model should probably be:

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

    It's not a major problem, but I find that as the number of associations with extra arguments get added, the less clear things become, so it's best to stick to the defaults whenever possible.

    0 讨论(0)
  • 2020-12-16 11:58

    If there are any methods or validation you want specific to a certain company type, you could sub class the company model. This employs a technique called single table inheritance. For more information check out this article: http://wiki.rubyonrails.org/rails/pages/singletableinheritance

    You would then have:

    #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
    

    As a result, you would have Company, Developer and Publisher models to use.

     Company.find(:all)
     Developer.find(:all)
     Publisher.find(:all)
    
    0 讨论(0)
提交回复
热议问题