2

How can I create a validation where committed presence needs to be true only if the challenge's category is habit?

class Challenge < ActiveRecord::Base
  CATEGORY = ['goal', 'habit']
  serialize :committed, Array
  validates :committed, presence: true, if: :habit # I also tried with 'habit' & 'Habit'
end
2
  • Where do you have the category stored at? Is it a column, or is in another table? Commented Oct 13, 2016 at 11:27
  • It's a column in challenge table, t.string "category" @Nobita Commented Oct 13, 2016 at 12:14

3 Answers 3

3

Since your category is called 'habit' (note, it is not 'Habit'), the validation would look as follows:

validates :committed, presence: true, if: ->(c) { c.category == 'habit' }

As a sidenote: I do not think your scopes will work, unless you have a column called categories in your challenges table. Thus, if your intention was to select challenges, which have category 'habit', the scope would look as follows:

scope :habit, -> { where(category: 'habit') }

EDIT

As per discussion in comments, if you want committed to be nil instead of [""] when nothing is there, add custom validation:

validate :committed_content

private

def committed_content
  self.committed = nil if committed.empty? || committed.all?(&:blank?)
  true
end
Sign up to request clarification or add additional context in comments.

9 Comments

Ah good point. Yea I'll take that out since I thought it was part of it, but I guess not. I'm getting an error though, syntax error, unexpected '.' ... true, if: ->(c) { c.category&.== 'habit' }
@AnthonyGalli.com Oh, may be you have Ruby <= 2.3. Try this: validates :committed, presence: true, if: ->(c) { c.category == 'habit' }
Been testing and I see the problem. I have this in the model serialize :committed, Array that I didn't include in the question :/ and so even if nothing is :committed I see it is passing in the database as committed: [""] instead of nil. You know I can make the validation work for this?
@AnthonyGalli.com so you do no want to have [""] in the database and want to prevent it from being saved? If yes, you should add content validation. let me edit the question once you confirm
Yea either that... or make it nil when empty. Either way works if you know how. Thanks good sir!
|
2
validates :committed, presence: true, :if => lambda { |c| c.category == 'Habit' } 

6 Comments

That gives an error: syntax error, unexpected => ...committed, presence: true, if => lambda { |c| c.categories ==... ... ^
@AnthonyGalli.com check now if is a symbol I have updated the answer
Thanks, but now I get uninitialized constant ActiveSupport::Callbacks::Callback::Habit
@AnthonyGalli.com Post your whole challenge.rb
Thanks for helping me narrow down the problem. It was a little more involved which Andrey helped figure out too.
|
1

You can have a method and use it like this:

validates :committed, presence: true, if: :habit?

def habit?
  self.category == 'habit'
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.