Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialRonald Jackson
9,229 PointsNeed help troubleshooting a custom validator for a serialize array field
How do I validate a serialize Array field in a Rails 4 app (Postgres db)? I have a Member model, which has a "goal" field, a serialized array. The form field is presented as a series of check-boxes where a member can identify fitness goal(s). A member can have multiple goals, but must have at least one goal. My understanding is Rails does not have a built in validation for a serialize array field. So, I'm trying to write a custom validator, but having trouble getting it to work properly.
This is my objective: I want to see the following behaviors in my application: If a member selects at least one goal then validation should pass and the record can be saved to the db. If a member fails to declare any goals then validation should fail and the record is not saved.
Here's relevant code from my member.rb (model) file:
serialize :goal, Array
GOALS = %w[ "Lose Fat", "Gain Muscle", "Get Toned", "Get Shredded", "Get Hulky", "Improve Balance", "Enhance Flexibility", "Maintain Current Weight" ]
validate :goal_check
protected
def goal_check
goal.each do |g|
errors.add(:goal, "#{g} is invalid; you must check at least one goal") unless GOALS.include? g
end
end
My custom validator is not working as desired. It prevents a member from being saved even when he/she checks at least one goal! Where did I go wrong in my "goal_check" method? How do I write a custom validator that will accomplish my objective? Thank you!
1 Answer
Seth Reece
32,867 PointsDoes GOALS.include?(g) work?
Ronald Jackson
9,229 PointsRonald Jackson
9,229 PointsSeth, When I run the code, my custom validator blocks a member from being saved even when he selects a goal in the array. It appears to ignore the checked goal, so I suspect there is a problem somewhere in my include code. To troubleshoot, I ran Launchy and see that a goal was clearly checked. Nevertheless, the validator prevents the record from being saved.
Seth Reece
32,867 PointsSeth Reece
32,867 PointsThe format for using include is: something.include?(variable) or something.include?("string").
You have GOALS.include? g
Ronald Jackson
9,229 PointsRonald Jackson
9,229 PointsI'm not sure how I need to change my code to fix the issue. Any suggestions for how I rework my existing code?
Seth Reece
32,867 PointsSeth Reece
32,867 PointsYes, in your goal.each iteration, change GOALS.include? g to GOALS.include?(g).
e.g.
Ronald Jackson
9,229 PointsRonald Jackson
9,229 PointsI changed the syntax as you recommended; unfortunately no luck. The custom validator is still not working correctly. As before, it prevents both scenarios: (1) a member without a goal from being saved as well as a (2) a member who correctly selects a goal in the Array field. Hmmm? Any other ideas I can try?
Seth Reece
32,867 PointsSeth Reece
32,867 PointsAhh missed this part. Your GOALS array is declared as GOALS = %w["foo", "bar"]. the %w syntax would be %w(foo bar) so try removing the %w, or removing all quotes, commas, change the square brackets to ().
Ronald Jackson
9,229 PointsRonald Jackson
9,229 PointsSeth - no luck getting this validator to work. I changed the syntax in the multiple ways you suggested, but it's still not validating correctly. Still can't save a member who correctly states a fitness goal. The validator does not appear to be able to distinguish when a goal as been checked (or not). This has me stumped but really curious now. I can't see anything obviously wrong. Other than this validation problem, the code works as expected ... no problems. Why won't this work correctly? I appreciate you help, Seth!
Seth Reece
32,867 PointsSeth Reece
32,867 PointsHmm.. I think you might need validates instead of validate below you GOALS array.
Ronald Jackson
9,229 PointsRonald Jackson
9,229 PointsChanging "validate" to "validates" throws an "ArgumentError: You need to supply at least one validation." Something seems amiss with my custom validator. I need to do some more research into how to validate serialized attributes. During my earlier research I found a gem for this exact purpose -- validates_serialized -- but since I'm writing the application to learn the Ruby/Rails, I plan to continue my efforts to get my custom validator to work. It may be something really simple but it eludes me for now. Not bad though, I'm learning a LOT of GOOD THINGS writing this application!