Reputation: 6578
In a Ruby on Rails 4 app, consider this data model:
Question:
id: int
# [...]
has_many: Answers
Answer:
id: int
question_id: int
# [...]
belongs_to: Question
has_many: Results through AnswerResult
AnswerResult:
id: int
answer_id: int
result_id: int
Result:
id: int
# [...]
has_many: Answers through AnswerResult
Using this model, consider this behaviour:
Now, here is my question:
After the user has answered all my questions, I end up having a hash of question IDs with the user's answer IDs. I want to find the result that belongs to that combination of answers.
How do I do that?
EDIT: Example: (as requested in comments)
Questions and answers, and their IDs
Gender: [Question #1]
- Male [Answer #1]
- Female [Answer #2]
Age: [Question #2]
- < 30 [Answer #3]
- 30 - 65 [Answer #4]
- > 65 [Answer #5]
Results:
Junior man [#1] bound to answers [#1, #3]
Senior man [#2] bound to answers [#1, #4]
Old man [#3] bound to answers [#1, #5]
Junior woman [#4] bound to answers [#2, #3]
Senior woman [#5] bound to answers [#2, #4]
Old woman [#6] bound to answers [#2, #5]
Input:
{
1 => 2, # Gender: female
2 => 4 # Age: 30-65
}
Function finds the result bound to answers #2 and #4
Output: Result #5: Senior woman
Upvotes: 1
Views: 264
Reputation: 4860
This is a difficult problem to resolve in SQL unless you know about the concept Relational Division in SQL.
The following query provides you the expected result
SELECT results.*
FROM results
INNER JOIN answer_results
ON results.id = answer_results.result_id
WHERE answer_results.answer_id IN (2, 4)
GROUP BY results.id
HAVING COUNT(results.id) = 2
Here you are a non-tested (you might change something) possible solution in ActiveRecord
answer_ids = input.map(&:last)
Result.joins(:answer_results).where("answer_results.answer_id IN (?)",
answer_ids).group('results.id').having('COUNT(results.id) = ?', answer_ids.size)
Upvotes: 1
Reputation: 9170
input = {
1 => 2, # Gender: female
2 => 4 # Age: 30-65
}
answers = input.inject([]){|ary, input| ary << input[1] } # [2,4]
results = {
"Junior man" => [1,3],
"Senior man" => [1,4],
"Old man" => [1,5],
"Junior woman" => [2,3],
"Senior woman" => [2,4],
"Old woman" => [2,5]
}
output = results.select {|k,v| v == answers} # "Senior woman" => [2,4]
output.keys[0] # "Senior Woman"
Upvotes: 1