'how to prepare csv data using associated model with missing values in rails
I'm trying to prepare a csv file which'll be generated from multiple tables. So I've my model setup like bellow
# Student
# attributes
:id, :name
class Student < ActiveRecord::Base
has_many :answers
end
# Question model
# attributes
:id, :question
class Question < ActiveRecord::Base
has_many :answers
end
# Answer model
# attributes
:id, :question_id, :student_id, :answer
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :student
end
Now I want to prepare a csv file.The header of the csv file will be the actual question of the Question model sorted(by id) and then prepare the csv data accordingly from Answer modoel .Now student might not answers all the questions.So I need to set n/a if a student doesn't answer a particular question. Offcourse the questions are sorted by id and the answer is also sorted by question_id. The output will be.
what_is_you_name, how_old_are_you, what_is_your_hobby
monsur, 18, playing football
ranjon, n/a, gardening
n/a, n/a, running
I query the Answer model.Because some of the Student skipped few question therefor there are no answer object present that's why the answer is in wrong position.
what_is_you_name, how_old_are_you, what_is_your_hobby
monsur, 18, playing football
ranjon, gardening
alex,running
So I need to set n/a if the particular student skipped a question .
I can't figure it out how to solve this problem.
Solution 1:[1]
You could overwrite attribute ie. if Answer model has field age you could do sth like:
def age
self.age || "n/a"
end
This should return age if it's present or "n/a" if it's nil.
If this does not solve your problem please provide a way how do you create CSV.
Solution 2:[2]
Ok after your explanation i came up with sth like this:
- Create default array
default = ['n/a', 'n/a', 'n/a'] - You should add
:question_idto.plucklike here:answers_arr = student.answers.order(question_id: :asc).pluck(:question_id, :answer)it gives you sth like[[1, "18"], [2, "playing football"]] - Replace values in default array with values from pluck:
answers_arr.each { |e| default[e[0] -1] = e[1] }sodefaultshould look like["18", "playing football", "n/a"]
EDIT Here is a code from the comment below that solved problem:
response = []
all_response = []
qs_id = [1,2.3]
answers.each do |answer|
qs_ids.each do |q_id|
if answer.question_id == q_id
response << answer.answer
else
response << 'n/a'
end
if qs_ids.last = q_id
all_response << response
end
end
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
