diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index ce9861547..51de9c678 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -15,6 +15,7 @@
//= require jquery-ui/widgets/datepicker
//= require jquery-ui/i18n/datepicker-es
//= require jquery-ui/widgets/autocomplete
+//= require jquery-ui/widgets/sortable
//= require jquery-fileupload/basic
//= require foundation
//= require turbolinks
@@ -71,6 +72,7 @@
//= require leaflet
//= require map
//= require polls
+//= require sortable
var initialize_modules = function() {
App.Comments.initialize();
@@ -110,6 +112,7 @@ var initialize_modules = function() {
App.PollsAdmin.initialize();
App.Map.initialize();
App.Polls.initialize();
+ App.Sortable.initialize();
};
$(function(){
diff --git a/app/assets/javascripts/sortable.js.coffee b/app/assets/javascripts/sortable.js.coffee
new file mode 100644
index 000000000..1af543f6a
--- /dev/null
+++ b/app/assets/javascripts/sortable.js.coffee
@@ -0,0 +1,9 @@
+App.Sortable =
+ initialize: ->
+ $(".sortable").sortable
+ update: (event, ui) ->
+ new_order = $(this).sortable('toArray', {attribute: 'data-answer-id'});
+ $.ajax
+ url: $('.sortable').data('js-url'),
+ data: {ordered_list: new_order},
+ type: 'POST'
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index aff55c88c..3f93ffa6b 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -18,4 +18,5 @@
@import 'datepicker_overrides';
@import 'jquery-ui/autocomplete';
@import 'autocomplete_overrides';
+@import 'jquery-ui/sortable';
@import 'leaflet';
diff --git a/app/controllers/admin/poll/questions/answers_controller.rb b/app/controllers/admin/poll/questions/answers_controller.rb
index 51c44dd94..bef176a22 100644
--- a/app/controllers/admin/poll/questions/answers_controller.rb
+++ b/app/controllers/admin/poll/questions/answers_controller.rb
@@ -39,6 +39,11 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController
render 'admin/poll/questions/answers/documents'
end
+ def order_answers
+ ::Poll::Question::Answer.order_answers(params[:ordered_list])
+ render nothing: true
+ end
+
private
def answer_params
diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb
index e6ef482a9..efcaf4635 100644
--- a/app/models/poll/question.rb
+++ b/app/models/poll/question.rb
@@ -10,7 +10,7 @@ class Poll::Question < ActiveRecord::Base
has_many :comments, as: :commentable
has_many :answers, class_name: 'Poll::Answer'
- has_many :question_answers, class_name: 'Poll::Question::Answer'
+ has_many :question_answers, -> { order 'given_order asc' }, class_name: 'Poll::Question::Answer'
has_many :partial_results
belongs_to :proposal
diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb
index b3324e57f..7514b85a4 100644
--- a/app/models/poll/question/answer.rb
+++ b/app/models/poll/question/answer.rb
@@ -1,5 +1,5 @@
class Poll::Question::Answer < ActiveRecord::Base
- include Galleryable
+ include Galleryable
include Documentable
documentable max_documents_allowed: 3,
max_file_size: 3.megabytes,
@@ -10,8 +10,26 @@ class Poll::Question::Answer < ActiveRecord::Base
has_many :videos, class_name: 'Poll::Question::Answer::Video'
validates :title, presence: true
+ validates :given_order, presence: true, uniqueness: { scope: :question_id }
+
+ before_validation :set_order, on: :create
def description
super.try :html_safe
end
+
+ def self.order_answers(ordered_array)
+ ordered_array.each_with_index do |answer_id, order|
+ find(answer_id).update_attribute(:given_order, (order + 1))
+ end
+ end
+
+ def set_order
+ next_position = self.class.last_position(question_id) + 1
+ self.given_order = next_position
+ end
+
+ def self.last_position(question_id)
+ where(question_id: question_id).maximum("given_order") || 0
+ end
end
diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb
index 5baabeafe..205b707fb 100644
--- a/app/views/admin/poll/questions/show.html.erb
+++ b/app/views/admin/poll/questions/show.html.erb
@@ -47,30 +47,32 @@
<%= t("admin.questions.show.answers.videos") %> |
- <% @question.question_answers.each do |answer| %>
-
- | <%= link_to answer.title, admin_answer_path(answer) %> |
- <%= answer.description %> |
-
- (<%= answer.images.count %>)
-
- <%= link_to t("admin.questions.show.answers.images_list"),
- admin_answer_images_path(answer) %>
- |
-
- (<%= answer.documents.count rescue 0 %>)
-
- <%= link_to t("admin.questions.show.answers.documents_list"),
- admin_answer_documents_path(answer) %>
- |
-
- (<%= answer.videos.count %>)
-
- <%= link_to t("admin.questions.show.answers.video_list"),
- admin_answer_videos_path(answer) %>
- |
-
- <% end %>
+
+ <% @question.question_answers.each do |answer| %>
+
+ | <%= link_to answer.title, admin_answer_path(answer) %> |
+ <%= answer.description %> |
+
+ (<%= answer.images.count %>)
+
+ <%= link_to t("admin.questions.show.answers.images_list"),
+ admin_answer_images_path(answer) %>
+ |
+
+ (<%= answer.documents.count rescue 0 %>)
+
+ <%= link_to t("admin.questions.show.answers.documents_list"),
+ admin_answer_documents_path(answer) %>
+ |
+
+ (<%= answer.videos.count %>)
+
+ <%= link_to t("admin.questions.show.answers.video_list"),
+ admin_answer_videos_path(answer) %>
+ |
+
+ <% end %>
+
<% if @question.video_url.present? %>
diff --git a/config/routes.rb b/config/routes.rb
index 83b5754d7..1fb74aa53 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -306,6 +306,7 @@ Rails.application.routes.draw do
resources :videos, controller: 'questions/answers/videos'
get :documents, to: 'questions/answers#documents'
end
+ post '/answers/order_answers', to: 'questions/answers#order_answers'
end
end
diff --git a/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb b/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb
new file mode 100644
index 000000000..6161e55e4
--- /dev/null
+++ b/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb
@@ -0,0 +1,5 @@
+class AddGivenOrderToPollQuestionAnswers < ActiveRecord::Migration
+ def change
+ add_column :poll_question_answers, :given_order, :integer, default: 1
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9adba12b1..b9a1524ab 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: 20171006145053) do
+ActiveRecord::Schema.define(version: 20171010143623) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -680,6 +680,7 @@ ActiveRecord::Schema.define(version: 20171006145053) do
t.string "title"
t.text "description"
t.integer "question_id"
+ t.integer "given_order", default: 1
end
add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree
diff --git a/spec/factories.rb b/spec/factories.rb
index a28471efc..69aa92c62 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -503,8 +503,8 @@ FactoryGirl.define do
factory :poll_question_answer, class: 'Poll::Question::Answer' do
association :question, factory: :poll_question
- sequence(:title) { |n| "Question title #{n}" }
- sequence(:description) { |n| "Question description #{n}" }
+ sequence(:title) { |n| "Answer title #{n}" }
+ sequence(:description) { |n| "Answer description #{n}" }
end
factory :poll_booth, class: 'Poll::Booth' do
diff --git a/spec/features/admin/poll/questions/answers/answers_spec.rb b/spec/features/admin/poll/questions/answers/answers_spec.rb
index 66918c4d8..48c2017f4 100644
--- a/spec/features/admin/poll/questions/answers/answers_spec.rb
+++ b/spec/features/admin/poll/questions/answers/answers_spec.rb
@@ -4,7 +4,7 @@ feature 'Answers' do
background do
admin = create(:administrator)
- login_as (admin.user)
+ login_as admin.user
end
scenario 'Create' do
@@ -24,9 +24,27 @@ feature 'Answers' do
expect(page).to have_content(description)
end
+ scenario 'Create second answer and place after the first one' do
+ question = create(:poll_question)
+ answer = create(:poll_question_answer, title: 'First', question: question, given_order: 1)
+ title = 'Second'
+ description = "Description"
+
+ visit admin_question_path(question)
+ click_link 'Add answer'
+
+ fill_in 'poll_question_answer_title', with: title
+ fill_in 'poll_question_answer_description', with: description
+
+ click_button 'Save'
+
+ expect(page.body.index('First')).to be < page.body.index('Second')
+ end
+
scenario 'Update' do
question = create(:poll_question)
- answer = create(:poll_question_answer, question: question, title: "Answer title")
+ answer = create(:poll_question_answer, question: question, title: "Answer title", given_order: 1)
+ answer2 = create(:poll_question_answer, question: question, title: "Another title", given_order: 2)
visit admin_answer_path(answer)
@@ -46,6 +64,8 @@ feature 'Answers' do
expect(page).to have_content(new_title)
expect(page).to_not have_content(old_title)
+
+ expect(page.body.index(new_title)).to be < page.body.index(answer2.title)
end
end
diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb
index f7dfd4d38..368597830 100644
--- a/spec/features/polls/answers_spec.rb
+++ b/spec/features/polls/answers_spec.rb
@@ -9,13 +9,15 @@ feature 'Answers' do
scenario "Index" do
question = create(:poll_question)
- answer1 = create(:poll_question_answer, question: question)
- answer2 = create(:poll_question_answer, question: question)
+ answer1 = create(:poll_question_answer, question: question, given_order: 1)
+ answer2 = create(:poll_question_answer, question: question, given_order: 2)
visit admin_question_path(question)
expect(page).to have_css(".poll_question_answer", count: 2)
+ expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title)
+
within("#poll_question_answer_#{answer1.id}") do
expect(page).to have_content answer1.title
expect(page).to have_content answer1.description
diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb
index 9fdb07255..fc21e1e5f 100644
--- a/spec/features/polls/polls_spec.rb
+++ b/spec/features/polls/polls_spec.rb
@@ -78,6 +78,30 @@ feature 'Polls' do
expect(page).to have_content(proposal_question.title)
end
+ scenario "Question answers appear in the given order" do
+ question = create(:poll_question, poll: poll)
+ answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 1)
+ answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 2)
+
+ visit poll_path(poll)
+
+ within("div#poll_question_#{question.id}") do
+ expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title)
+ end
+ end
+
+ scenario "More info answers appear in the given order" do
+ question = create(:poll_question, poll: poll)
+ answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 1)
+ answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 2)
+
+ visit poll_path(poll)
+
+ within('div.poll-more-info-answers') do
+ expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title)
+ end
+ end
+
scenario 'Non-logged in users' do
question = create(:poll_question, poll: poll)
answer1 = create(:poll_question_answer, question: question, title: 'Han Solo')