Dennis Nedry
Dennis Nedry

Reputation: 4748

Rails validation: Only N records can be true

How would you write a validation that checks if a certain amount of records already have an attribute that is true?

class BlogPost
   scope :onStartpage, -> { where(onStartpage: true) }
   validate :number_on_startpage

   def number_on_startpage
     return unless onStartpage?
     errors.add(:foobar, 'foo') if Blog::Post.where(onStartpage: true).count > 3
   end
end

Like in the example above - I want to make sure that there are no more than three BlogPosts with the attribute onStartpage set to true.

But it's not working because when I want to save the record the count is still 2. And all later updates get rejected because the count is too high.

Upvotes: 0

Views: 299

Answers (1)

Samy Kacimi
Samy Kacimi

Reputation: 1238

The problem is that your validation will be checked for previous blog posts, even if you just wanted to change the title for instance.

You could check your validation only if the attribute onStartPage has changed.

Also, you could change the condition to >=, as if you already have 3 articles with that attribute, 3 is not strictly superior to 3...so it will only return false after you have 4 articles with onStartpage set to true.

class BlogPost
   scope :onStartpage, -> { where(onStartpage: true) }
   validate :number_on_startpage

   def number_on_startpage
     return unless onStartpage_changed?
     errors.add(:foobar, 'foo') if Blog::Post.where(onStartpage: true).count >= 3
   end
end

Upvotes: 2

Related Questions