Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iagirre question ansers ordenable #2037

Merged

Conversation

iagirre
Copy link

@iagirre iagirre commented Oct 10, 2017

Where

What

Make the answers sortable from the admin page, so that they appear in the given order when user enters the poll.

How

  • I added a column to the poll_question_answers table named given_order
  • In order to make the answers sortable, I added the jquery-ui widget sortable to the table in the admins panel (where admin can add new questions). Admins drag and drop questions inside the table to sort them.
  • I added an order to the relation between question and answers, so that every time we use question.question_answers they appear ordered by given_order field.

Screenshots

iagirre-answer-order_1
Drag and drop to change the order

iagirre-answer-order_2
The order has been changed

iagirre-answer-order_3

User sees the new order

iagirre-answer-order_4

Test

I increased the test coverage to test if:

  • the new answers are created with an order.
  • the answers appear in the right order when updated.
  • the admin sees the questions answers in the right order.
  • the answers of a question appear in the right order.
  • the more info answers appear in the right order.

Deployment

Not needed.

Warnings

  • When creating new answers, the order of the new one will be the last one created + 1. I mean:
    There is already an answer with given_order = 1. The next will be given_order = 2, and so on. If it's the first one, it will be given_order = 1.
  • I'm not sure if some more style will be needed in the admins page so that they know how to drag and drop.

ordered_array.each_with_index do |answer_id, order|
answer = find(answer_id)
answer.update_attribute(:given_order, (order + 1))
answer.save
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update_attribute saves the record already. I would refactor this 3 lines into just find(answer_id).update_attribute(:given_order, (order + 1))

end

def set_order
last_position = Poll::Question::Answer.where(question_id: question_id).maximum("given_order") || 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need Poll::Question::Answer self reference

@@ -0,0 +1,5 @@
class AddGivenOrderToPollQuestionAnswers < ActiveRecord::Migration
def change
add_column :poll_question_answers, :given_order, :integer
Copy link
Collaborator

@bertocq bertocq Oct 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one! I started a quick refactor to add this but found myself in the pitfall of creating a column named order that raised many issues 🙈 this name is better

Although by reading all code seems to me that the given_order values will always start from 1, right? Would it make sense to set a default: 1 just as a reminder on the code and as well as a security measure?

Also I think if given_order is an attribute needed there should be a presence validation on the model (as well as one that checks its unique for the question_id (only one Answer on a particular order for its Question)

@@ -24,9 +24,27 @@
expect(page).to have_content(description)
end

scenario 'Create second answer and place after the first one' do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -9,6 +9,7 @@ def new

def create
@answer = ::Poll::Question::Answer.new(answer_params)
@answer.set_order
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since there might be other ways to create an answer (think through rake task, console, etc...) and a value at the given_order attribute is always needed. This set_order method shouldn't be called here, but on a before_create on the Poll Question Answer model

@bertocq
Copy link
Collaborator

bertocq commented Oct 10, 2017

Really nice the default order in the relation between questions and answers 👏 cool trick :)

There's an additional place where we'll need answers ordered where that default order won't help sadly :( https://github.com/consul/consul/blob/master/app/views/polls/show.html.erb#L82 on Madrid's fork we did this "hack" sorting in Ruby but that's not really a nice way to do it either :D https://github.com/ayuntamientomadrid/consul/blob/master/app/views/polls/show.html.erb#L98.

I think the trick here would be to instead of @poll.questions.map(&:question_answers).flatten.each use Poll::Question::Answer.where(question: @poll.question).each but we'll be needing an spec to check that (we hotfixed it on madrid not even time to add spec to it there)

We can fix this in a second PR if you think it will be too much for this one (tell me and I'll open an Issue)

@zamuro zamuro force-pushed the iagirre-question-ansers-ordenable branch from 1d6644b to 644d09e Compare October 11, 2017 07:44
@@ -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
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally used before_validation on: :create to set the order, because if it was set before_create, the validation run before all of that (so, before set_order method) and it failled.
For the 1st there was no problem, but for the 2nd it couldn't pass the validation and it couldn't create the record.

sequence(:title) { |n| "Question title #{n}" }
sequence(:description) { |n| "Question description #{n}" }
sequence(:title) { |n| "Answer title #{n}" }
sequence(:description) { |n| "Answer description #{n}" }
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the name for the poll_question_answer because it made conflicts with the poll_question name when running specs (they had the same name, but, as I understand, the answers should be named 'Answer title X' instead of 'Question title X').

Copy link
Collaborator

@bertocq bertocq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @iagirre 👏

@bertocq bertocq merged commit 5ff0047 into consuldemocracy:master Oct 11, 2017
@iagirre iagirre deleted the iagirre-question-ansers-ordenable branch January 16, 2018 07:22
javierm added a commit to javierm/consul that referenced this pull request Jun 17, 2019
…esults_links

Don't show links to disabled budget results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants