我正在试图找出设计导轨模型的最佳方法.出于示例的目的,假设我正在构建一个字符数据库,这可能有几个不同的固定属性.例如:
Character
- Morality (may be "Good" or "Evil")
- Genre (may be "Action", "Suspense", or "Western")
- Hair Color (may be "Blond", "Brown", or "Black")
Run Code Online (Sandbox Code Playgroud)
... 等等.
因此,对于Character模型,有几个属性,我希望基本上有一个固定的可能选择列表.
我希望用户能够创建一个角色,并希望他们从每个可用选项中选择一个.我还希望能够让用户使用这些属性中的每一个进行搜索...(即,"显示'好'中的字符',来自'悬疑'类型,并且具有'棕色'头发".
我可以想到几种方法来做到这一点......
1:为每个属性创建一个字符串并验证有限的输入.
在这种情况下,我将在字符表上定义一个字符串列"Morality",然后使用其中指定的选项具有类常量,然后针对该类常量进行验证.
找到好的角色就好Character.where(:morality=>'Good').
这很简单,缺点是如果我想为属性添加更多细节,例如描述"Good"和"Evil",以及用户可以查看给定道德的所有字符的页面.
2:为每个属性创建一个模型
在这种情况下Character belongs_to Morality,会有一个Morality模型和一个moralities包含两个记录的表:Morality id:1, name:Good等等.
找到好的角色就像Morality.find_by_name('Good').characters......或者
Character.where(:morality=> Morality.find(1).
这样可以正常工作,但这意味着您有几个表只存在少量预定义属性.
3:为属性创建STI模型
在这种情况下,我可以像#2一样,除了创建一个通用的"CharacterAttributes"表,然后将其子类化为"MoralityAttribute"和"GenreAttribute"等.这使得只有一个表用于许多属性,否则它看起来大致相同作为想法#2.
所以,这些是我能想到解决这个问题的三种方式.
我的问题是,你将如何实现这一点,为什么?
你会使用上面的方法之一,如果是这样的话?你会做些不同的事吗?我特别有兴趣听听您将采取的方法的性能考虑因素.我知道这是一个广泛的问题,谢谢你的任何意见.
编辑: 我在这个问题上添加了250的赏金(超过我的声誉的10%!!),因为我可以真正使用一些更多关于利弊/选项的扩展讨论.如果有人能给我一个非常可靠的例子说明他们采取了哪种方法以及为什么它值得+250,那么我会放弃给那些有建设性的东西的人投票.
我真的很痛苦我的应用程序的这方面的设计,现在是时候实现它.在此先感谢任何有益的讨论!!
最后注意:
谢谢大家的深思熟虑和有趣的答案,所有这些都很好,对我很有帮助.最后(在赏金到期之前就来了!)我非常感谢Blackbird07的回答.虽然每个人都提出了很好的建议,但就我个人来说,他是最有用的.我之前并没有真正意识到枚举的想法,因此我发现它解决了我在应用程序中遇到的许多问题.我会鼓励发现这个问题的每个人阅读所有的答案,提供了许多好的方法.
我想在我正在进行的sone迁移中创建一个枚举字段,我尝试在谷歌搜索,但我无法在迁移中找到方法
我发现的唯一的事情是
t.column :status, :enum, :limit => [:accepted, :cancelled, :pending]
Run Code Online (Sandbox Code Playgroud)
但看起来上面的代码只在rails 1.xxx上运行,因为我正在运行rails 2.0
这就是我尝试但它失败了
class CreatePayments < ActiveRecord::Migration
def self.up
create_table :payments do |t|
t.string :concept
t.integer :user_id
t.text :notes
t.enum :status, :limit => [:accepted, :cancelled, :pending]
t.timestamps
end
end
def self.down
drop_table :payments
end
end
Run Code Online (Sandbox Code Playgroud)
那么,如果不允许,您认为什么是一个好的解决方案?只是一个文本字段,并从模型验证?