Best place to store model specific constants in ra

2020-05-14 22:17发布

问题:

I have a field type in a model called user which is an int in the db. The value of the int speficies the type of store it is. Example:

  • 0 = mom
  • 1 = dad
  • 2 = grand mother
  • and so on

I have several other fields like this so it's overkill to create association tables.

Instead of checking for those int values over the place in conditional statements in model and controller logic, is there a place in rails to store these constants.

So that I could do this from my models and controllers?

if myuser.type == MOM
elsif myuser.type == GRAND_MOTHER

EDIT: Solution I went with at the end:

In model:

  # constants
  TYPES = {
    :mom => 0,
    :dad => 1,
    :grandmother => 2,
    :grandfather => 3
  }

In logic:

if u.type == User::TYPES[:mom]

Even though it's longer, I felt it to be more intuitive for other developers when they're reading my code. Thanks to Taro below for this solution.

回答1:

Something like:

class User < ActiveRecord::Base

  TYPES = %w{ mom dad grandmother grandfather son }

  TYPES.each_with_index do |meth, index|
    define_method("#{meth}?") { type == index }
  end

end


u = User.new
u.type = 4
u.mom? # => false
u.son? # => true


回答2:

Since Rails 4.1, there is support for ActiveRecord::Enum.

There's a useful tutorial here, but in short:

# models/user.rb
class User < ActiveRecord::Base
  enum family_role: [ :mum, :dad, :grandmother]
end

# logic elsewhere
u = User.first
u.family_role = 'mum'
u.mum? # => true
u.family_role # => 'mum'

Note: To convert from your current scheme (where your database already stores numbers corresponding to values), you should use the hash syntax:

enum family_role: { mum: 0, dad: 1, grandmother: 2 }

I would additionally propose that you reserve 0 for the default state, but that's just one convention and not critical.



回答3:

You should avoid using "type" as a model's column name unless you use Single Table Inheritance.

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Single+table+inheritance



回答4:

One way you be to write an file in initializers folder or lib folder

say app_contants.rb and in this file you can write

MOM=1

DAD=2
  1. Incase you write a initializer you can do

user.type == mom

2.If you create an lib file make it a module

 module app_constants
    mom = 1
    dad = 2
  end 

and simply include this module wherever you need