Skip to content

Instantly share code, notes, and snippets.

@jeffrwells
Last active December 27, 2015 09:49
Show Gist options
  • Save jeffrwells/7306896 to your computer and use it in GitHub Desktop.
Save jeffrwells/7306896 to your computer and use it in GitHub Desktop.
Use a postgres string[] column for both singular entries and arrays. If the question type is a MULTISELECT, then the attribute will act like an array, but if not, it acts like a String. However, this particular String does not respond to <<, so that it will throw errors if you try to use it. This way, if the developer is has an array, and trying…
class CreateQuizzes < ActiveRecord::Migration
def change
create_table :quiz_questions do |t|
t.integer :quiz_id
t.string :format, :default => 'MultiChoice' #MultiChoice, MultiSelect, or Field
t.string :answer, array: true, default: []
t.string :options, array: true, default: []
t.timestamps
end
end
end
class QuizQuestion < ActiveRecord::Base
MULTISELECT = 'MultiSelect'
MULTICHOICE = 'MultiChoice'
FIELD = 'Field'
QUESTION_TYPES = [MULTISELECT, MULTICHOICE, FIELD]
after_initialize -> { self[:answer] = []; self[:options] = [] }
def answer
if(format == MULTISELECT)
# array answer
self[:answer]
else
#There should only be one answer, String
res = self[:answer].first
unless res.nil?
class << res
undef_method :<<
end
end
return res
end
end
def answer=(other)
if(format == MULTISELECT)
if(other.is_a?(Array))
self[:answer] = other
else
raise ArgumentError, ':answer for MultiChoice is an array, use `answer<<(String)` to add an item, or `answer=Array` to set to a new set'
end
else
#There should only be one answer
self[:answer][0] = other
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment