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 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

3 Comments

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.
Missing extra conditions constrain: :conditions => { {:id => question_id}, {:question_choices => {:id => answer} }
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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.