How can I make it so that at least two option records are required to submit a product?
class Product < ActiveRecord::Base
belongs_to :user
has_many :options, :dependent => :destroy
accepts_nested_attributes_for :options, :allow_destroy => :true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
validates_presence_of :user_id, :created_at
validates :description, :presence => true, :length => {:minimum => 0, :maximum => 500}
end
class Option < ActiveRecord::Base
belongs_to :product
validates :name, :length => {:minimum => 0, :maximum => 60}
end
If your form allows records to be deleted then .size
will not work as it includes the records marked for destruction.
My solution was:
validate :require_two_options
private
def require_two_options
i = 0
product_options.each do |option|
i += 1 unless option.marked_for_destruction?
end
errors.add(:base, "You must provide at least two option") if i < 2
end
Tidier code, tested with Rails 5:
class Product < ActiveRecord::Base
OPTIONS_SIZE_MIN = 2
validate :require_two_options
private
def options_count_valid?
options.reject(&:marked_for_destruction?).size >= OPTIONS_SIZE_MIN
end
def require_two_options
errors.add(:base, 'You must provide at least two options') unless options_count_valid?
end
end
Just a consideration about karmajunkie answer: I would use size
instead of count
because if some built (and not saved) nested object has errors, it would not be considered (its not on database yet).
class Product < ActiveRecord::Base
#... all your other stuff
validate :require_two_options
private
def require_two_options
errors.add(:base, "You must provide at least two options") if options.size < 2
end
end
class Product < ActiveRecord::Base
#... all your other stuff
validate :require_two_options
private
def require_two_options
errors.add(:base, "You must provide at least two options") if options.size < 2
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With