Как проверить, есть ли в модели определенный столбец / атрибут?

123

У меня есть метод, который должен пройти через хэш и проверить, существует ли каждый ключ в таблице моделей, иначе он удалит ключ / значение.

например

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

а в таблице Number есть только один столбец, поэтому два будут удалены.

Как проверить, есть ли у модели атрибут?

DMIX
источник

Ответы:

205

Для класса

Используйте Class.column_names.include? attr_nameгде attr_name- строковое имя вашего атрибута.

В таком случае: Number.column_names.include? 'one'

Например

Используйте record.has_attribute?(:attr_name)или record.has_attribute?('attr_name')(Rails 3.2+) или record.attributes.has_key? attr_name.

В этом случае: number.has_attribute?(:one)или number.has_attribute?('one')илиnumber.attributes.has_key? 'one'

Энди Стюарт
источник
Для бонусных баллов используйте Hash#select:number_hash.select { |key, value| Number.column_names.include? key }
hgmnz
28
В Rails 3.2+ используйте, number.has_attribute?который принимает символ или строку
Марк-Андре Лафортюн
Я считаю, что если объект делегирует метод другому объекту, этот метод ошибочно предполагает, что столбец существует. Я проверял свои модели на предмет тех, у которых был user, но вместо этого мне приходилось искать, user_idпоскольку некоторые модели делегировали user.
MattyB
Hash#has_key?устарел в пользуHash#key?
Charles Hamel
Как насчет использования attribute_method? для класса:Number.attribute_method? 'one'
ouranos
13

Если вам также нужно проверить псевдонимы, вы можете использовать Number.method_defined? attr_nameили number.class.method_defined? attr_name.

Мне пришлось сделать это для объекта Mongoid, у которого были псевдонимы полей.

Ник
источник
Я обнаружил, ModelName.attribute_method? :attr_nameчто сработало в моем экземпляре
somedirection
10

В вашем экземпляре объекта вы также можете использовать defined? instance.attributeили instance.respond_to? :attribute.
Это более общее решение для проверки атрибута модели или любого метода.

Alter Lagos
источник
3
Имейте в виду:instance.respond_to?(:attribute) == false ; instance.attribute ; instance.respond_to?(:attribute) == true
kbrock