¿Cómo verificar si un modelo tiene una determinada columna / atributo?

123

Tengo un método que necesita recorrer un hash y verificar si cada clave existe en una tabla de modelos, de lo contrario, eliminará la clave / valor.

por ejemplo

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

y la tabla Número solo tiene una columna: una, por lo que se eliminarán dos.

¿Cómo verifico si un modelo tiene un atributo o no?

dMix
fuente

Respuestas:

205

Para una clase

Use Class.column_names.include? attr_namedonde attr_nameestá el nombre de cadena de su atributo.

En este caso: Number.column_names.include? 'one'

Por una instancia

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

En este caso: number.has_attribute?(:one)o number.has_attribute?('one')onumber.attributes.has_key? 'one'

Andy Stewart
fuente
Para usar puntos de bonificación Hash#select:number_hash.select { |key, value| Number.column_names.include? key }
hgmnz
28
En Rails 3.2+, uso number.has_attribute?que acepta un Símbolo o una Cadena
Marc-André Lafortune
Creo que si un objeto delega un método a otro objeto, este método sugerirá erróneamente que la columna existe. Estaba comprobando mis modelos para los que tenían un user, pero en su lugar tuve que buscar user_idya que algunos modelos delegaron al usuario.
MattyB
Hash#has_key?está en desuso a favor deHash#key?
Charles Hamel
¿Qué tal el uso de attribute_method? para una clase:Number.attribute_method? 'one'
ouranos
13

Si necesita verificar también los alias, puede usar Number.method_defined? attr_nameo number.class.method_defined? attr_name.

Tuve que hacer esto para un objeto Mongoid que tenía alias de campos.

Mella
fuente
Encontré que ModelName.attribute_method? :attr_namefue lo que funcionó en mi caso
somedirection
10

En su objeto de instancia, puede usar también defined? instance.attributeo instance.respond_to? :attribute.
Estas son soluciones más genéricas para verificar un atributo del modelo o cualquier método también.

Alter Lagos
fuente
3
Tenga en cuenta:instance.respond_to?(:attribute) == false ; instance.attribute ; instance.respond_to?(:attribute) == true
kbrock