2014-01-17 66 views
1

如何处理rails中的枚举?我已经使用了这个,但没有找到任何干净的解决方案。到目前为止,我已经在使用interaction_type_id的模型中提出了以下关注。这是我在数据库枚举表中的外键。使用这种方法,我没有给所有在我的代码IDS使用,但保存该涉及interact_type一个对象的时候,我可以说如何处理rails枚举?

myobject.interaction_type = :file_download 

这可以再用,因为关注正确的ID坚持的数据库(请参阅下面的关注 - 包含在使用枚举的模型中)将返回正确的ID。

module InteractionTypeEnum 
    extend ActiveSupport::Concern 

    included do 
    INTERACTION_TYPE = { file_download: 1, email: 2, telesales: 3, registration: 4, enrolment: 5 } 
    end 

    def interaction_type 
    INTERACTION_TYPE.key(read_attribute(:interaction_type_id)).to_s.gsub('_',' ').capitalize 
    end 

    def interaction_type=(s) 
    write_attribute(:interaction_type_id, INTERACTION_TYPE[s]) 
    end 
end  

这只是感觉很重。必须有一种更简单/更清洁的方式。现在当试图为此编写测试时,它变得更加混乱。

希望在代码和数据库中枚举的大多数原因是性能(代码)和报告(数据库)。

任何帮助表示赞赏。谢谢。

回答

1

我建议active_enum宝石。从自己的文件

例如,如果你有一个整数列名为sex的类User

class User < ActiveRecord::Base 
    enumerate :sex do 
    value :name => 'Male' 
    value :name => 'Female' 
    end 
end 

,也可以定义在一个单独的类枚举:

class Sex < ActiveEnum::Base 
    value 1 => 'Male' 
    value 2 => 'Female' 
end 

class User < ActiveRecord::Base 
    enumerate :sex, :with => Sex 
end 

我喜欢它提供了抽象的功能,并且可以避免为了存储枚举值而创建整个数据库表。

+0

不错的解决方案,但可以说现在将用户存储在数据库中,并且您想通过后端访问用户的性别。你是说这应该作为一个字符串存储在数据库中 - 男性,女性。如果你的枚举集合增加到10个,并且在那之后不会改变,会发生什么。你不希望这个信息在数据库的表中吗?在某些情况下,您还可能想要扩展枚举以包含其他信息,例如排名/顺序或说明。我看到这是如何有用和干净的,但它可能有点有限。 –

+0

它作为一个整数存储在数据库中,并且比我在这里复制粘贴的功能多得多(例如,您可以将扩展信息添加到您描述的枚举中。)如果只是为了更多地了解它,看看它是否适合你的目的,我建议给它一个去;我在多个项目中使用过它,从来没有遇到任何问题。但当然,这不是唯一的解决方案(我相信也有其他枚举宝石,或者您可以像其他答案一样推出自己的枚举类型),并且我没有太多的投入,其他建议也可以工作。 – GMA

+0

我已经签出github。看起来非常好,但它似乎不支持rails 4.当我在代码中启用config.extend_classes = [ActiveRecord :: Base]并尝试运行rails控制台时,我得到/Users/ryanme/.rvm/gems/ruby [email protected]_rails_4_0/gems/activerecord-4.0.2/lib/active_record/dynamic_matchers.rb:22:在'method_missing':未定义的方法'class_inheritable_accessor'为ActiveRecord :: Base:Class(NoMethodError)--- ----从我读过的class_inheritable_accessor已被弃用。 –

0

我使用下面的方法,说我有

class PersonInfo < ActiveRecord::Base 
    belongs_to :person_info_type 
end 

PersonInfoType是一个简单的域表,将含有可能类型的信息。

然后我如下的代码我的模型:

class PersonInfoType < ActiveRecord::Base 

    PHONE = 1 
    EMAIL = 2 
    URL = 3 

end 

我有一个种子填充与相应数据的数据库。

所以分配当一些人信息可以这样做

person.person_infos << PersonInfo.create(:info => 'http://www.some-url.com', :person_info_type_id => PersonInfoType::URL) 

该代码然后可以进一步清理使用关系:

class PersonInfo 

    belongs_to :person_info_type 

    def self.phones 
    PersonInfo.where(:person_info_type_id => PersonInfoType::PHONE) 
    end 

end 

person.person_infos << PersonInfo.phones.create(:info => '555 12345')