Я знаю, что может потребоваться поле, добавив validates_presence_of :field
к модели. Однако, как мне нужно, чтобы хотя бы одно поле было обязательным, не требуя какого-либо конкретного поля?
заблаговременно
- Deb
Я знаю, что может потребоваться поле, добавив validates_presence_of :field
к модели. Однако, как мне нужно, чтобы хотя бы одно поле было обязательным, не требуя какого-либо конкретного поля?
заблаговременно
- Deb
Вы можете использовать:
validate :any_present?
def any_present?
if %w(field1 field2 field3).all?{|attr| self[attr].blank?}
errors.add :base, "Error message"
end
end
EDIT: обновлено от исходного ответа для Rails 3+ в соответствии с комментарием.
Но вы должны указать имена полей вручную.
Вы можете получить все столбцы содержимого модели с помощью Model.content_columns.map(&:name)
, но она будет включать столбцы created_at
и updated_at
, и это, вероятно, не то, что вы хотите.
Добавьте к вашей модели метод validate
:
def validate
if field1.blank? and field2.blank? and field3.blank? # ...
errors.add_to_base("You must fill in at least one field")
end
end
Здесь используется многоразовая версия:
class AnyPresenceValidator < ActiveModel::Validator
def validate(record)
unless options[:fields].any?{|attr| record[attr].present?}
record.errors.add(:base, :blank)
end
end
end
Вы можете использовать его в своей модели с помощью:
validates_with AnyPresenceValidator, fields: %w(field1 field2 field3)
Я считаю, что что-то вроде следующего может работать
class MyModel < ActiveRecord::Base
validate do |my_model|
my_model.my_validation
end
def my_validation
errors.add_to_base("Your error message") if self.blank?
#or self.attributes.blank? - not sure
end
end
Идем дальше с правильным ответом @Votya, вот способ получить все столбцы, кроме created_at и updated_at (и, возможно, любые другие, которые вы хотите выкинуть):
# Get all column names as an array and reject the ones we don't want
Model.content_columns.map(&:name).reject {|i| i =~ /(created|updated)_at/}
Например:
1.9.3p327 :012 > Client.content_columns.map(&:name).reject {|i| i =~ /(created|updated)_at/}
=> ["primary_email", "name"]