views:

79

answers:

1

I'm trying to create a page where users can select cast their vote for certain items in the order they choose.

There are a dynamic amount of options to choose from, e.g. there might be three options to choose from [apples, bananas, oranges], and therefore each option has a select against it, with each select then having three order of preference values [1,2,3].

The results set could be something like:

[apples,2],[bananas,3],[oranges,1]

And I'll eventually manipulate this so that I have [oranges,apples,bananas] in a array.

How do I validate that all options have been chosen, and that they can be seen to be in order?

Do I need to pass the data thru a loop that orders them by the chosen preference, and then counts to see if there is a missing preference?

Or am I missing a wonderful plugin that already does this?

+2  A: 

This will do the validation, and check there are votes for precisely 1, 2, 3 and no others.

s = [[:apples,2],[:bananas,3],[:oranges,1]]
s.map(&:last).sort == (1..3).to_a

To get the sorted array, use this:

s.sort{|a,b| a.last <=> b.last}.map(&:first)

EDIT (explanation): the first block works by extracting the second item of each array in the array, then checks it's equal to the range 1..3. This validates uniqueness and presence of each item. To use this to validate in rails, you'll need a custom validator.

For the custom validator (season to taste):

validate :valid_votes?

def valid_votes?
  unless votes.map(&:last).sort == (1..3).to_a
    errors.add(:votes, 'are missing, duplicated or invalid')
  end
end
Peter
That looks pretty interesting, could you explain it a little? And how would I validate using the code you mentioned?
Les
Wow, thanks Peter - that's great stuff! I'm guessing I could pass in the length of the expected array as a parameter to the validation? The number of options is probably going to vary each time the user has a choice.
Les
Absolutely you could pass in the parameter (anytime you see 3, replace with n).
Peter