views:

44

answers:

1

I have a piece of code that checks that a survey response picked by user to a survey question is in fact one of valid choices:

Question.find_by_id(question_id).question_choices.all(:select => 'id').map {|x| x.id}.include?(user_choice_id)

Is there an easier way? Thanks!

+1  A: 

At the very least the question_choices.all(:select => 'id').map {|x| x.id} component can be rewritten, as ActiveRecord provides a method for this question_choice_ids.

You can also just do find instead of find_by_id. I know that find will raise an exception if nothing is found, but so will calling question_choices on nil in your example, anyway:

Question.find(question_id).question_choice_ids.include?(user_choice_id)

# or 

# Rails 2 (will run 2 queries unless you use :include)
Question.find(question_id).question_choices.first(:conditions => {:id => user_choice_id})

# Rails 3 (will only run 1 query)
Question.find(question_id).question_choices.where(:id => user_choice_id).first
bjeanes
Thank you for your insightful reply. You understand my problem correctly. However I don't think that the last two code fragments(using conditions and named_scope) will work. Since the only parameter entered is the choice_id. This would find the question for which this choice is valid, but not check whether a give choice is valid for given question.
Swartz
Missing extra conditions constrain: :conditions => { {:id => question_id}, {:question_choices => {:id => answer} }
Swartz
Ah you are right, it would need the `question_id` too. I didn't write a test application to test them, but at least you got the gist. I am updating my examples with another way to do it that's nicer
bjeanes