Лучшее место для хранения модельных констант в рельсах 3.1?
У меня есть поле типа в модели с именем user, которая является int в db. Значение int speficies - тип хранилища. Пример:
- 0 = mom
- 1 = папа
- 2 = grand mother
- и т.д.
У меня есть несколько других полей, подобных этому, поэтому он переполняет создание таблиц ассоциаций.
Вместо того, чтобы проверять эти значения int по месту в условных операторах в логике модели и контроллера, есть ли место в рельсах для хранения этих констант.
Чтобы я мог делать это с моих моделей и контроллеров?
if myuser.type == MOM
elsif myuser.type == GRAND_MOTHER
EDIT: решение, с которым я пошел в конце:
В модели:
# constants
TYPES = {
:mom => 0,
:dad => 1,
:grandmother => 2,
:grandfather => 3
}
В логике:
if u.type == User::TYPES[:mom]
Несмотря на то, что это было дольше, я чувствовал, что это более интуитивно понятно для других разработчиков, когда они читают мой код. Спасибо Таро ниже для этого решения.
Ответы
Ответ 1
Что-то вроде:
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
С Rails 4.1 поддерживается поддержка ActiveRecord:: Enum.
Там полезный учебник здесь, но вкратце:
# 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'
Примечание. Чтобы преобразовать из текущей схемы (где ваша база данных уже хранит числа, соответствующие значениям), вы должны использовать синтаксис хеша:
enum family_role: { mum: 0, dad: 1, grandmother: 2 }
Я бы дополнительно предложил зарезервировать 0
для состояния по умолчанию, но это только одно соглашение и не критично.
Ответ 3
Вам следует избегать использования "типа" в качестве имени столбца модели, если вы не используете одностраничное наследование.
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Single+table+inheritance
Ответ 4
Один из способов записать файл в папку инициализаторов или папку lib
скажите app_contants.rb, и в этом файле вы можете написать
MOM=1
DAD=2
- Если вы напишете инициализатор
вы можете сделать
user.type == mom
2.Если вы создаете файл lib
сделать его модулем
module app_constants
mom = 1
dad = 2
end
и просто включите этот модуль, где вам нужно