另一个基本的Rails问题:
我有一个数据库表,需要包含对特定数据类型的两个不同记录的引用。
假设的例子:我正在制作视频游戏数据库。我有一张“公司”表。我希望每个“视频游戏”条目只有一个开发人员和一个发布者。
我知道如果我想拥有一家公司,我可以做类似的事情:
script/generate Videogame company:references
但我需要两家公司。我宁愿不使用连接表,因为只能有两个给定的数据类型,我需要它们是不同的。
似乎答案应该非常明显,但我无法在互联网上找到它。
答案 0 :(得分:46)
只是为了整理一下,在您的迁移中,您现在也可以这样做:
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"
这不是一个主要问题,但我发现随着额外参数的关联数量增加,事情变得越不清晰,所以最好尽可能坚持默认值。
答案 1 :(得分:9)
我不知道如何使用script / generate执行此操作。
无论如何不使用脚本/生成更容易显示基本思想。您希望视频游戏表/模型中有两个字段,用于保存公司表/模型的外键。
我会告诉你我认为代码会是什么样子,但我没有测试过,所以我可能错了。
您的迁移文件包含:
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"
您还提到希望两家公司不同,您可以在检查developer_id != publisher_id
的模型中进行验证。
答案 2 :(得分: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)