Wie überprüfe ich, ob ein Modell eine bestimmte Spalte / ein bestimmtes Attribut hat?

123

Ich habe eine Methode, die einen Hash durchlaufen und prüfen muss, ob jeder Schlüssel in einer Modelltabelle vorhanden ist. Andernfalls wird der Schlüssel / Wert gelöscht.

beispielsweise

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

und die Zahlentabelle hat nur eine: eine Spalte, so dass: zwei gelöscht werden.

Wie überprüfe ich, ob ein Modell ein Attribut hat oder nicht?

dMix
quelle

Antworten:

205

Für eine Klasse

Verwenden Sie Class.column_names.include? attr_namewo attr_nameist der String-Name Ihres Attributs.

In diesem Fall: Number.column_names.include? 'one'

Zum Beispiel

Verwenden Sie record.has_attribute?(:attr_name)oder record.has_attribute?('attr_name')(Rails 3.2+) oder record.attributes.has_key? attr_name.

In diesem Fall: number.has_attribute?(:one)oder number.has_attribute?('one')odernumber.attributes.has_key? 'one'

Andy Stewart
quelle
Für Bonuspunkte verwenden Sie Hash#select:number_hash.select { |key, value| Number.column_names.include? key }
hgmnz
28
Verwenden Sie in Rails 3.2+, number.has_attribute?das ein Symbol oder eine Zeichenfolge akzeptiert
Marc-André Lafortune
Ich glaube, wenn ein Objekt eine Methode an ein anderes Objekt delegiert, deutet diese Methode fälschlicherweise darauf hin, dass die Spalte vorhanden ist. Ich überprüfte meine Modelle auf solche, die eine userhatten, musste aber stattdessen suchen, user_idda einige Modelle Benutzer delegierten.
MattyB
Hash#has_key?wird zugunsten vonHash#key?
Charles Hamel
Wie wäre es mit attribute_method? für eine Klasse:Number.attribute_method? 'one'
Ouranos
13

Wenn Sie auch nach Aliasen suchen müssen, können Sie Number.method_defined? attr_nameoder verwenden number.class.method_defined? attr_name.

Ich musste dies für ein mongoides Objekt tun, das Felder mit Alias ​​hatte.

Nick
quelle
Ich fand, ModelName.attribute_method? :attr_namewas in meiner Instanz
funktionierte
10

In Ihrem Instanzobjekt können Sie auch defined? instance.attributeoder verwenden instance.respond_to? :attribute.
Dies ist eine allgemeinere Lösung, um ein Modellattribut oder eine beliebige Methode zu überprüfen.

Alter Lagos
quelle
3
Bitte beachten Sie:instance.respond_to?(:attribute) == false ; instance.attribute ; instance.respond_to?(:attribute) == true
Kbrock