在 Rails 中实现查找表
我当前正在使用(或尝试使用)查找表来表示包含枚举字符串的列。我与我的团队进行了广泛的讨论,以确保这是我们想要的方向,并决定追求它,但不幸的是,我们都不知道如何使用迁移将查找表绑定到列,以及是否有更改在模型/控制器/视图中进行以支持这种新行为。
我已经在谷歌上进行了广泛的搜索,但没有找到这样做的好例子,所以我希望有人可以告诉我一个我在搜索中错过的教程的精彩链接,或者描述如何做到这一点。我也很想知道是否有一个非官方(或官方)的 Railsy 模式。
提前致谢。
I'm currently using (or trying to use) a lookup table to represent a column that contains an enumerated string. I've had extensive discussions with my team to make sure this is the direction we want to go and have decided to pursue it but unfortunately none of us know how to tie the lookup table to the column using migrations and if there are changes that have to be made in the model/controller/views to support this new behavior.
I've googled this extensively and have not found good examples of doing this so I'm hoping someone can either tell me of a wonderful link to a tutorial I just missed in my search, or describe how to do this. I also would love to know if there is an unofficial (or official) Railsy pattern for this.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您正在寻找一种轻量级的方法来对枚举/配置进行建模而不创建单独的表,那么一定要查看 ActiveHash:
https://github.com/zilkey/active_hash
If you're looking for a light-weight way to model enumerations/configuration without creating a separate table, definitely check out ActiveHash:
https://github.com/zilkey/active_hash
我遇到了和你一样的问题,并通过创建一个 gem 来解决它,该 gem 将动态查找表透明地添加到模型中。我在这里写了一篇博客: http://www.codelord.net/2011/08/09/guest-post-lookup-tables-with-ruby-on-rails/
代码在这里:https://github.com/Nimster/RailsLookup
I encountered the same problem as you, and solved it by creating a gem that adds a dynamic lookup table transparently into the model. I've blogged about it here: http://www.codelord.net/2011/08/09/guest-post-lookup-tables-with-ruby-on-rails/
And the code is here: https://github.com/Nimster/RailsLookup
我知道这是一个老问题,但由于它仍然是谷歌上的热门问题,我想我会分享我的解决方案,它被打包为一个宝石。看看
https://github.com/blackrat/acts_as_enumeration
从自述文件中:
因此,如果数据库表有一个名为“name”的列,声明
actions_as_enumeration :name
将选择该列中的所有项目,并将它们以散列形式映射到其主键值。
此外,它还创建实例方法 is_#{key},其中 key 是该列中的所有值,is?(array) 和 is_not?(array) 用于检查该数组中的类型。
以 name 作为我们的列示例,类方法 id_for_name 将返回该映射的主键值,而 valid_name?(value) 将说明表是否包含具有该值的 name 列中的条目。
最后,缺少的方法允许 is_ 和 is_not 链接方法,例如 is_paul_or_michael_or_luke?其效果与 (is_paul? || is_michael? || is_luke?) 或 is?(:paul, :michael, :luke) 和 is_not_paul_or_michael_or_like 效果相同 !(is_paul || is_michael? || is_luke? ) 或 !is?(:paul, :michael, :luke)
警告:由于 method_missing 使用的机制,如果某人实际上有名字“not bruce”,则组合查询不能使用它作为第一个元素。即“不”不仅仅是“不布鲁斯”。
那么 is_not_bruce_or_paul 的组合?必须写成is_paul_or_not_bruce?才能达到想要的效果。 is_not_not_bruce_or_paul 没问题,但发生这种情况的可能性大约与 Monty Python 草图之外有人实际称呼“not bruce”的可能性一样。
(这意味着它可能会,所以在更改代码以支持新条目之前,请尝试仅更改顺序)
I know this is an old question, but since it's still the top hit on google, I thought I'd share my solution to it which is packaged up as a gem. Take a look at
https://github.com/blackrat/acts_as_enumeration
From the readme:
So if a database table had a column called "name", declaring
acts_as_enumeration :name
would select all of the items in that column and map them in a hash to their primary key values.
In addition, it creates the instance methods is_#{key} where key is all of the values in that column, is?(array) and is_not?(array) that check for type within that array.
Keeping name as our column example, the class methods id_for_name will return the primary key value for that mapping and valid_name?(value) will say if the table contains and entry in the name column with that value.
Finally, the method missing allows for is_ and is_not chaining of methods, such as is_paul_or_michael_or_luke? which has the same effect as (is_paul? || is_michael? || is_luke?) or is?(:paul, :michael, :luke) and is_not_paul_or_michael_or_like which has the same effect as !(is_paul || is_michael? || is_luke?) or !is?(:paul, :michael, :luke)
CAVEAT: Due to the mechanism that the method_missing uses, if someone actually had the name "not bruce", the combination query cannot use this as the first element. i.e. "not " not just "not bruce".
So a combination of is_not_bruce_or_paul? would have to be written is_paul_or_not_bruce? to have the desired effect. is_not_not_bruce_or_paul is fine, but the chances of this happening are about as likely as someone actually called "not bruce" outside of a Monty Python sketch.
(Which means it probably will, so before you change code to support a new entry, try just changing the order)