Validate presence before custom validation

validates :place_id, :title, :level, :start_at, :end_at, :presence => true validate :event_takes_place_in_one_day, :event_is_not_in_past

  def event_takes_place_in_one_day     self.start_at.day == self.end_at.day   end   def event_is_not_in_past     admissible_range = DateTime.now.beginning_of_day..DateTime.now.end_of_month     admissible_range.cover?(self.start_at) && admissible_range.cover?(self.end_at)   end

and bang! error when start_at or end_at is nil.

undefined method `to_datetime' for nil:NilClass

app/models/meeting.rb:22:in `cover?' app/models/meeting.rb:22:in `event_is_not_in_past' app/controllers/meetings_controller.rb:18:in `create'

You realise that validations are performed when the attempt is made to save to the database?

Otherwise it might be helpful to show us the cover method.

Colin

cover? is the method of ActiveSupport. Ahh yeah, I loose it:) So what should I do - create a new inheritance from ActiveModel::Validator for each check?

Sorry, I don't understand what you are trying to do. Please explain in more detail what the problem is that you are trying to solve.

If the problem is that you need non-nil dates in the controller then then you could just check them.

Colin

Sorry, English is not my native language:) Application have a Meeting model with start_at and end_at DateTime type attributes, which indicate a start and the end of the meeting respectively. I need to implement next logic start_at < end_at (that it starts after than end) start_at.day == end_at.day (meeting ends within one day) and also meeting can be created only for the current month.

Sorry, English is not my native language:) Application have a Meeting model with start_at and end_at DateTime type attributes, which indicate a start and the end of the meeting respectively. I need to implement next logic start_at < end_at (that it starts after than end) start_at.day == end_at.day (meeting ends within one day) and also meeting can be created only for the current month.

Ok I see the problem, it is that the validations are not performed in the order that you hoped. I don't know whether you can control this. One solution is just to add checks into your validate methods to stop them crashing. Something like def event_is_not_in_past     admissible_range = DateTime.now.beginning_of_day..DateTime.now.end_of_month     self.start_at.nil? || self.end_at.nil? || (admissible_range.cover?(self.start_at) && admissible_range.cover?(self.end_at))   end

Then that test will pass but your presence validations will fail.

Colin

Great, according to this logic system will take care for error messages and this will not take place, right? :slight_smile: if start_at.nil?     errors.add(:start_at, "can't be blank")     return if start_end.nil?     errors.add(:end_at, "can't be blank")     return

Sorry, I do not understand what you are asking? Is this a continuation of your first question or is it a new question? If is is a new question then it would be better to start a new thread.

Colin