脚手架 ActiveRecord:相同数据类型的两列

发布于 2024-07-12 00:37:07 字数 336 浏览 4 评论 0原文

另一个基本的 Rails 问题:

我有一个数据库表,需要包含对特定数据类型的两个不同记录的引用。

假设的例子:我正在制作一个视频游戏数据库。 我有一张“公司”表格。 我希望每个“视频游戏”条目都有一位开发商和一位发行商。

我知道,如果我想拥有一家公司,我可以这样做:

script/generate Videogame company:references

但我需要拥有两家公司。 我不想使用连接表,因为给定的数据类型只能有两种,而且我需要它们是不同的。

看起来答案应该很明显,但我在互联网上找不到它。

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 example: I'm making a video game database. I have a table for "Companies." I want to have exactly one developer and exactly one publisher for each "Videogame" entry.

I know that if I want to have one company, I can just do something like:

script/generate Videogame company:references

But I need to have both companies. I'd rather not use a join table, as there can only be exactly two of the given data type, and I need them to be distinct.

It seems like the answer should be pretty obvious, but I can't find it anywhere on the Internet.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜嗑 2024-07-19 00:37:07

只是为了整理一下,在迁移中您现在还可以执行以下操作:

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"

这不是一个主要问题,但我发现随着关联的数量随着额外参数的添加,事情变得越不清晰,因此最好尽可能坚持默认值。

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.

空袭的梦i 2024-07-19 00:37:07

我不知道如何使用脚本/生成来做到这一点。

无论如何,在不使用脚本/生成的情况下,基本思想更容易展示。 您需要视频游戏表/模型中的两个字段来保存公司表/模型的外键。

我将向您展示我认为代码的样子,但我还没有测试过它,所以我可能是错的。

您的迁移文件具有:

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 的模型中的验证中处理这一点。

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.

国粹 2024-07-19 00:37:07

如果您想要特定于特定公司类型的任何方法或验证,您可以对公司模型进行子类化。 这采用了一种称为单表继承的技术。 有关更多信息,请查看这篇文章: 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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文