Sempre torci o nariz para criação de modelos de domínios (status.rb, genero.rb, tipo.rb, ...), principalmente quando o usuário não terá acesso para adicionar ou editar estes dados. Uma alternativa para isto é criar um modulo onde os domínios serão hashs:
# app/utilities/data_base.rb
module DataBase
def self.gender
{ "Male" => 1,
"Female" => 2
}
end
end
# app/models/user.rb
class User < ActiveRecord::Base
validates :gender, inclusion: { in: DataBase.gender.values }
end
# views/users/_form.html.rb - use simple_form
<%= user_form.input :gender, collection: DataBase.gender %>
Basta informar qual é a descrição do valor desejado:
# app/models/user.rb
class User < ActiveRecord::Base
validates :gender, inclusion: { in: DataBase.gender.values }
scope :male, -> { where(gender: DataBase.gender["Male"]) }
end
Passar a descrição desta maneira, me incomoda um pouco pois o código pouco legível. Costumo contornar isto, desta forma:
# app/utilities/data_base.rb
module DataBase
def self.gender(key = nil)
data = { "Male" => 1,
"Female" => 2
}
key.nil? ? data : data[key.to_s]
end
end
# app/models/user.rb
class User < ActiveRecord::Base
validates :gender, inclusion: { in: DataBase.gender.values }
scope :male, -> { where(gender: DataBase.gender :male) }
end
Aqui esta a principal vantagem de não criar modelos para os domínios
# app/utilities/data_base.rb
module DataBase
def self.gender(key = nil)
data = { I18n.t('base.gender.male') => 1,
I18n.t('base.gender.female') => 2
}
key.nil? ? data : data[ I18n.t("base.gender.#{key.to_s}") ]
end
end
# config/locales/pt-BR/pt-BR/base.pt-BR.yml
br:
base:
gender:
male: "Homem"
female: "Mulher"
O código para acessar o valor do domínio voltou a ficar ruim. Melhorando ele:
# app/utilities/data_base.rb
module DataBase
def self.gender(key = nil)
data = { I18n.t('base.gender.male') => 1,
I18n.t('base.gender.female') => 2
}
key.nil? ? data : data[ DataBase.i18n(:gender, key) ]
end
def self.i18n(domain, key)
I18n.t("base.#{domain.to_s}.#{key.to_s}")
end
end
Outro ponto interessante desta abordagem é a flexibilidade em exibir os domínios. Exemplo: Em uma tabela polimorfica para endereço deve ser exibido para o campo address_type as opcões Residencial e Comercial quando for User e Matriz e Filial para associação com Company.
# app/utilities/data_base.rb
module DataBase
def self.address_type(type, key = nil)
if type == "User"
data = { I18n.t('base.address.home') => 1,
I18n.t('base.address.work') => 2
}
else
data = { I18n.t('base.address.headquarter') => 1,
I18n.t('base.address.subsidiary') => 2
}
end
key.nil? ? data : data[ DataBase.i18n(:address, key) ]
end
# ... omitted self.i18n
end
- Todo acesso a domínio irá criar um hash
- Caso mais de uma aplicação acesse a base de dados, existirá código replicado
- Quando executar querys em um console, terá a necessidade de colocar 'hardcode' e não poderá fazer joins
- Aplicação mais simples
- Flexibilidade para os domínios
- Internacionalização
- Validações não acessam base de dados.