Como verificar se um modelo tem uma determinada coluna / atributo?

123

Eu tenho um método que precisa fazer um loop através de um hash e verificar se cada chave existe em uma tabela de modelos, caso contrário, ele excluirá a chave / valor.

por exemplo

number_hash = { :one => "one", :two => "two" }

e a tabela Number possui apenas uma: uma coluna; portanto, duas serão excluídas.

Como verifico se um modelo tem um atributo ou não?

dMix
fonte

Respostas:

205

Para uma aula

Use Class.column_names.include? attr_namewhere attr_nameé o nome da string do seu atributo.

Nesse caso: Number.column_names.include? 'one'

Para uma instância

Use record.has_attribute?(:attr_name)ou record.has_attribute?('attr_name')(Rails 3.2+) ou record.attributes.has_key? attr_name.

Nesse caso: number.has_attribute?(:one)ou number.has_attribute?('one')ounumber.attributes.has_key? 'one'

Andy Stewart
fonte
Para obter pontos de bônus, use Hash#select:number_hash.select { |key, value| Number.column_names.include? key }
hgmnz 10/11/09
28
No Rails 3.2+, o uso number.has_attribute?que aceita um símbolo ou uma String
Marc-André Lafortune
Acredito que se um objeto delega um método para outro objeto, esse método sugere erroneamente que a coluna existe. Eu estava checando meus modelos em busca de modelos que tivessem um user, mas precisava procurar, user_idpois alguns modelos delegavam usuário.
MattyB
Hash#has_key?é reprovado em favor deHash#key?
Charles Hamel
Que tal usar o attribute_method? para uma aula:Number.attribute_method? 'one'
ouranos 25/05
13

Se você precisar verificar aliases também, poderá usar Number.method_defined? attr_nameou number.class.method_defined? attr_name.

Eu tive que fazer isso para um objeto mongóide que tinha campos com alias.

usuario
fonte
Achei ModelName.attribute_method? :attr_nameque foi o que funcionou na minha instância
somedirection 11/07/19
10

No seu objeto de instância, você também pode usar defined? instance.attributeou instance.respond_to? :attribute.
Estas são soluções mais genéricas para verificar também um atributo de modelo ou qualquer método.

Alter Lagos
fonte
3
Tenha em mente:instance.respond_to?(:attribute) == false ; instance.attribute ; instance.respond_to?(:attribute) == true
kbrock