diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb new file mode 100644 index 000000000..b8815cf2d --- /dev/null +++ b/app/models/poll/question.rb @@ -0,0 +1,47 @@ +class Poll::Question < ActiveRecord::Base + include Measurable + + acts_as_paranoid column: :hidden_at + include ActsAsParanoidAliases + + belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' + + has_many :comments, as: :commentable + has_many :answers + has_and_belongs_to_many :geozones + belongs_to :proposal + + validates :title, presence: true + validates :question, presence: true + validates :summary, presence: true + validates :author, presence: true + + validates :title, length: { in: 4..Poll::Question.title_max_length } + validates :description, length: { maximum: Poll::Question.description_max_length } + validates :question, length: { in: 10..Poll::Question.question_max_length } + + scope :sort_for_list, -> { order('proposal_id IS NULL', :created_at)} + scope :for_render, -> { includes(:author, :proposal) } + + def description + super.try :html_safe + end + + def valid_answers + (super.try(:split, ',').compact || []).map(&:strip) + end + + def copy_attributes_from_proposal(proposal) + if proposal.present? + self.author = proposal.author + self.author_visible_name = proposal.author.name + self.proposal_id = proposal.id + self.title = proposal.title + self.description = proposal.description + self.summary = proposal.summary + self.question = proposal.question + self.geozones = Geozone.all + end + end + +end diff --git a/db/migrate/20161028104156_create_poll_questions.rb b/db/migrate/20161028104156_create_poll_questions.rb new file mode 100644 index 000000000..13c8ac1e8 --- /dev/null +++ b/db/migrate/20161028104156_create_poll_questions.rb @@ -0,0 +1,21 @@ +class CreatePollQuestions < ActiveRecord::Migration + def change + create_table :poll_questions do |t| + t.references :proposal, index: true, foreign_key: true + t.references :poll, index: true, foreign_key: true + t.references :author, index: true # foreign key added later due to rails 4 + t.string :author_visible_name + t.string :title + t.string :question + t.string :summary + t.string :valid_answers + t.text :description + t.integer :comments_count + t.datetime :hidden_at + + t.timestamps + end + + add_foreign_key :poll_questions, :users, column: :author_id + end +end diff --git a/db/migrate/20161028143204_create_geozones_poll_questions.rb b/db/migrate/20161028143204_create_geozones_poll_questions.rb new file mode 100644 index 000000000..68077c510 --- /dev/null +++ b/db/migrate/20161028143204_create_geozones_poll_questions.rb @@ -0,0 +1,10 @@ +class CreateGeozonesPollQuestions < ActiveRecord::Migration + def change + create_table :geozones_poll_questions do |t| + t.references :geozone, index: true, foreign_key: true + t.integer :question_id, index: true + end + + add_foreign_key :geozones_poll_questions, :poll_questions, column: :question_id + end +end diff --git a/db/schema.rb b/db/schema.rb index d1862bf11..a8e6f83b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161020112156) do +ActiveRecord::Schema.define(version: 20161028143204) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -211,6 +211,14 @@ ActiveRecord::Schema.define(version: 20161020112156) do t.string "census_code" end + create_table "geozones_poll_questions", force: :cascade do |t| + t.integer "geozone_id" + t.integer "question_id" + end + + add_index "geozones_poll_questions", ["geozone_id"], name: "index_geozones_poll_questions_on_geozone_id", using: :btree + add_index "geozones_poll_questions", ["question_id"], name: "index_geozones_poll_questions_on_question_id", using: :btree + create_table "identities", force: :cascade do |t| t.integer "user_id" t.string "provider" @@ -287,6 +295,26 @@ ActiveRecord::Schema.define(version: 20161020112156) do t.datetime "updated_at", null: false end + create_table "poll_questions", force: :cascade do |t| + t.integer "proposal_id" + t.integer "poll_id" + t.integer "author_id" + t.string "author_visible_name" + t.string "title" + t.string "question" + t.string "summary" + t.string "valid_answers" + t.text "description" + t.integer "comments_count" + t.datetime "hidden_at" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "poll_questions", ["author_id"], name: "index_poll_questions_on_author_id", using: :btree + add_index "poll_questions", ["poll_id"], name: "index_poll_questions_on_poll_id", using: :btree + add_index "poll_questions", ["proposal_id"], name: "index_poll_questions_on_proposal_id", using: :btree + create_table "poll_voters", force: :cascade do |t| t.integer "booth_id" t.string "document_number" @@ -583,12 +611,17 @@ ActiveRecord::Schema.define(version: 20161020112156) do add_foreign_key "annotations", "users" add_foreign_key "failed_census_calls", "users" add_foreign_key "flags", "users" + add_foreign_key "geozones_poll_questions", "geozones" + add_foreign_key "geozones_poll_questions", "poll_questions", column: "question_id" add_foreign_key "identities", "users" add_foreign_key "locks", "users" add_foreign_key "managers", "users" add_foreign_key "moderators", "users" add_foreign_key "notifications", "users" add_foreign_key "organizations", "users" + add_foreign_key "poll_questions", "polls" + add_foreign_key "poll_questions", "proposals" + add_foreign_key "poll_questions", "users", column: "author_id" add_foreign_key "users", "geozones" add_foreign_key "valuators", "users" end diff --git a/spec/factories.rb b/spec/factories.rb index 21abd6554..abeff338c 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -296,6 +296,15 @@ FactoryGirl.define do end end + factory :poll_question, class: 'Poll::Question' do + association :author, factory: :user + sequence(:title) { |n| "Question title #{n}" } + sequence(:summary) { |n| "Question summary #{n}" } + sequence(:description) { |n| "Question description #{n}" } + sequence(:question) { |n| "Question question #{n}" } + valid_answers { Faker::Lorem.words(3).join(', ') } + end + factory :organization do user responsible_name "Johnny Utah" diff --git a/spec/models/poll/question_spec.rb b/spec/models/poll/question_spec.rb new file mode 100644 index 000000000..92e019027 --- /dev/null +++ b/spec/models/poll/question_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' + +RSpec.describe Poll::Question, type: :model do + + describe "#valid_answers" do + it "gets a comma-separated string, but returns an array" do + q = create(:poll_question, valid_answers: "Yes, No") + expect(q.valid_answers).to eq(["Yes", "No"]) + end + end + + describe "#copy_attributes_from_proposal" do + it "copies the attributes from the proposal" do + create_list(:geozone, 3) + p = create(:proposal) + q = create(:poll_question) + q.copy_attributes_from_proposal(p) + expect(q.author).to eq(p.author) + expect(q.author_visible_name).to eq(p.author.name) + expect(q.proposal_id).to eq(p.id) + expect(q.title).to eq(p.title) + expect(q.question).to eq(p.question) + expect(q.geozones).to eq(Geozone.all) + end + end + +end