Make questions translatable
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
class Admin::Poll::QuestionsController < Admin::Poll::BaseController
|
class Admin::Poll::QuestionsController < Admin::Poll::BaseController
|
||||||
include CommentableActions
|
include CommentableActions
|
||||||
|
include Translatable
|
||||||
|
|
||||||
load_and_authorize_resource :poll
|
load_and_authorize_resource :poll
|
||||||
load_and_authorize_resource :question, class: 'Poll::Question'
|
load_and_authorize_resource :question, class: 'Poll::Question'
|
||||||
@@ -55,11 +56,15 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def question_params
|
def question_params
|
||||||
params.require(:poll_question).permit(:poll_id, :title, :question, :proposal_id)
|
attributes = [:poll_id, :title, :question, :proposal_id]
|
||||||
|
params.require(:poll_question).permit(*attributes, *translation_params(Poll::Question))
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_params
|
def search_params
|
||||||
params.permit(:poll_id, :search)
|
params.permit(:poll_id, :search)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def resource
|
||||||
|
@poll_question ||= Poll::Question.find(params[:id])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ class Poll::Question < ActiveRecord::Base
|
|||||||
acts_as_paranoid column: :hidden_at
|
acts_as_paranoid column: :hidden_at
|
||||||
include ActsAsParanoidAliases
|
include ActsAsParanoidAliases
|
||||||
|
|
||||||
|
translates :title, touch: true
|
||||||
|
globalize_accessors
|
||||||
|
|
||||||
belongs_to :poll
|
belongs_to :poll
|
||||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<%= form_for(@question, url: form_url) do |f| %>
|
<%= render "admin/shared/globalize_locales", resource: @question %>
|
||||||
|
|
||||||
|
<%= translatable_form_for(@question, url: form_url) do |f| %>
|
||||||
|
|
||||||
<%= render 'shared/errors', resource: @question %>
|
<%= render 'shared/errors', resource: @question %>
|
||||||
|
|
||||||
@@ -6,13 +8,14 @@
|
|||||||
|
|
||||||
<div class="small-12">
|
<div class="small-12">
|
||||||
<div class="small-12 medium-6 large-4">
|
<div class="small-12 medium-6 large-4">
|
||||||
|
<% select_options = Poll.all.map { |p| [p.name, p.id] } %>
|
||||||
<%= f.select :poll_id,
|
<%= f.select :poll_id,
|
||||||
options_for_select(Poll.pluck(:name, :id)),
|
options_for_select(select_options),
|
||||||
prompt: t("admin.questions.index.select_poll"),
|
prompt: t("admin.questions.index.select_poll"),
|
||||||
label: t("admin.questions.new.poll_label") %>
|
label: t("admin.questions.new.poll_label") %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= f.text_field :title %>
|
<%= f.translatable_text_field :title %>
|
||||||
|
|
||||||
<div class="small-12 medium-4 large-2 margin-top">
|
<div class="small-12 medium-4 large-2 margin-top">
|
||||||
<%= f.submit(class: "button success expanded", value: t("shared.save")) %>
|
<%= f.submit(class: "button success expanded", value: t("shared.save")) %>
|
||||||
|
|||||||
@@ -47,10 +47,18 @@ end
|
|||||||
section "Creating Poll Questions & Answers" do
|
section "Creating Poll Questions & Answers" do
|
||||||
Poll.find_each do |poll|
|
Poll.find_each do |poll|
|
||||||
(1..4).to_a.sample.times do
|
(1..4).to_a.sample.times do
|
||||||
question = Poll::Question.create!(author: User.all.sample,
|
title = Faker::Lorem.sentence(3).truncate(60) + '?'
|
||||||
title: Faker::Lorem.sentence(3).truncate(60) + '?',
|
question = Poll::Question.new(author: User.all.sample,
|
||||||
poll: poll)
|
title: title,
|
||||||
Faker::Lorem.words((2..4).to_a.sample).each do |answer|
|
poll: poll)
|
||||||
|
I18n.available_locales.map do |locale|
|
||||||
|
neutral_locale = locale.to_s.downcase.underscore.to_sym
|
||||||
|
Globalize.with_locale(neutral_locale) do
|
||||||
|
question.title = "#{title} (#{locale})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
question.save!
|
||||||
|
Faker::Lorem.words((2..4).to_a.sample).each do |title|
|
||||||
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
|
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
|
||||||
Poll::Question::Answer.create!(question: question,
|
Poll::Question::Answer.create!(question: question,
|
||||||
title: answer.capitalize,
|
title: answer.capitalize,
|
||||||
@@ -194,6 +202,13 @@ section "Creating Poll Questions from Proposals" do
|
|||||||
description: Faker::ChuckNorris.fact)
|
description: Faker::ChuckNorris.fact)
|
||||||
end
|
end
|
||||||
question.copy_attributes_from_proposal(proposal)
|
question.copy_attributes_from_proposal(proposal)
|
||||||
|
title = question.title
|
||||||
|
I18n.available_locales.map do |locale|
|
||||||
|
neutral_locale = locale.to_s.downcase.underscore.to_sym
|
||||||
|
Globalize.with_locale(neutral_locale) do
|
||||||
|
question.title = "#{title} (#{locale})"
|
||||||
|
end
|
||||||
|
end
|
||||||
question.save!
|
question.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -209,6 +224,13 @@ section "Creating Successful Proposals" do
|
|||||||
description: Faker::ChuckNorris.fact)
|
description: Faker::ChuckNorris.fact)
|
||||||
end
|
end
|
||||||
question.copy_attributes_from_proposal(proposal)
|
question.copy_attributes_from_proposal(proposal)
|
||||||
|
title = question.title
|
||||||
|
I18n.available_locales.map do |locale|
|
||||||
|
neutral_locale = locale.to_s.downcase.underscore.to_sym
|
||||||
|
Globalize.with_locale(neutral_locale) do
|
||||||
|
question.title = "#{title} (#{locale})"
|
||||||
|
end
|
||||||
|
end
|
||||||
question.save!
|
question.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
13
db/migrate/20180731173147_add_poll_question_translations.rb
Normal file
13
db/migrate/20180731173147_add_poll_question_translations.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class AddPollQuestionTranslations < ActiveRecord::Migration
|
||||||
|
|
||||||
|
def self.up
|
||||||
|
Poll::Question.create_translation_table!(
|
||||||
|
title: :string
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
Poll::Question.drop_translation_table!
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
11
db/schema.rb
11
db/schema.rb
@@ -847,6 +847,17 @@ ActiveRecord::Schema.define(version: 20180813141443) do
|
|||||||
|
|
||||||
add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree
|
add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree
|
||||||
|
|
||||||
|
create_table "poll_question_translations", force: :cascade do |t|
|
||||||
|
t.integer "poll_question_id", null: false
|
||||||
|
t.string "locale", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.string "title"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "poll_question_translations", ["locale"], name: "index_poll_question_translations_on_locale", using: :btree
|
||||||
|
add_index "poll_question_translations", ["poll_question_id"], name: "index_poll_question_translations_on_poll_question_id", using: :btree
|
||||||
|
|
||||||
create_table "poll_questions", force: :cascade do |t|
|
create_table "poll_questions", force: :cascade do |t|
|
||||||
t.integer "proposal_id"
|
t.integer "proposal_id"
|
||||||
t.integer "poll_id"
|
t.integer "poll_id"
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ feature 'Admin poll questions' do
|
|||||||
click_link "Create question"
|
click_link "Create question"
|
||||||
|
|
||||||
select 'Movies', from: 'poll_question_poll_id'
|
select 'Movies', from: 'poll_question_poll_id'
|
||||||
fill_in 'poll_question_title', with: title
|
fill_in 'poll_question_title_en', with: title
|
||||||
|
|
||||||
click_button 'Save'
|
click_button 'Save'
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ feature 'Admin poll questions' do
|
|||||||
click_link "Create question"
|
click_link "Create question"
|
||||||
|
|
||||||
expect(page).to have_current_path(new_admin_question_path, ignore_query: true)
|
expect(page).to have_current_path(new_admin_question_path, ignore_query: true)
|
||||||
expect(page).to have_field('poll_question_title', with: proposal.title)
|
expect(page).to have_field('poll_question_title_en', with: proposal.title)
|
||||||
|
|
||||||
select 'Proposals', from: 'poll_question_poll_id'
|
select 'Proposals', from: 'poll_question_poll_id'
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ feature 'Admin poll questions' do
|
|||||||
|
|
||||||
old_title = question1.title
|
old_title = question1.title
|
||||||
new_title = "Potatoes are great and everyone should have one"
|
new_title = "Potatoes are great and everyone should have one"
|
||||||
fill_in 'poll_question_title', with: new_title
|
fill_in 'poll_question_title_en', with: new_title
|
||||||
|
|
||||||
click_button 'Save'
|
click_button 'Save'
|
||||||
|
|
||||||
|
|||||||
147
spec/features/translations/poll_questions_spec.rb
Normal file
147
spec/features/translations/poll_questions_spec.rb
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature "Translations" do
|
||||||
|
|
||||||
|
context "Polls" do
|
||||||
|
|
||||||
|
let(:poll) { create(:poll, name_en: "Name in English",
|
||||||
|
name_es: "Nombre en Español",
|
||||||
|
summary_en: "Summary in English",
|
||||||
|
summary_es: "Resumen en Español",
|
||||||
|
description_en: "Description in English",
|
||||||
|
description_es: "Descripción en Español") }
|
||||||
|
|
||||||
|
background do
|
||||||
|
admin = create(:administrator)
|
||||||
|
login_as(admin.user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Questions" do
|
||||||
|
|
||||||
|
let(:question) { create(:poll_question, poll: poll,
|
||||||
|
title_en: "Question in English",
|
||||||
|
title_es: "Pregunta en Español") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
@edit_question_url = edit_admin_question_path(question)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Poll select box" do
|
||||||
|
|
||||||
|
scenario "translates the poll name in options", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
expect(page).to have_select('poll_question_poll_id', options: [poll.name_en])
|
||||||
|
|
||||||
|
select('Español', from: 'locale-switcher')
|
||||||
|
|
||||||
|
expect(page).to have_select('poll_question_poll_id', options: [poll.name_es])
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "uses fallback if name is not translated to current locale", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
expect(page).to have_select('poll_question_poll_id', options: [poll.name_en])
|
||||||
|
|
||||||
|
select('Français', from: 'locale-switcher')
|
||||||
|
|
||||||
|
expect(page).to have_select('poll_question_poll_id', options: [poll.name_es])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Add a translation", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
select "Français", from: "translation_locale"
|
||||||
|
fill_in 'poll_question_title_fr', with: 'Question en Français'
|
||||||
|
|
||||||
|
click_button 'Save'
|
||||||
|
expect(page).to have_content "Changes saved"
|
||||||
|
|
||||||
|
visit @edit_question_url
|
||||||
|
expect(page).to have_field('poll_question_title_en', with: 'Question in English')
|
||||||
|
|
||||||
|
click_link "Español"
|
||||||
|
expect(page).to have_field('poll_question_title_es', with: 'Pregunta en Español')
|
||||||
|
|
||||||
|
click_link "Français"
|
||||||
|
expect(page).to have_field('poll_question_title_fr', with: 'Question en Français')
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Update a translation", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
click_link "Español"
|
||||||
|
fill_in 'poll_question_title_es', with: 'Pregunta correcta en Español'
|
||||||
|
|
||||||
|
click_button 'Save'
|
||||||
|
expect(page).to have_content "Changes saved"
|
||||||
|
|
||||||
|
visit poll_path(poll)
|
||||||
|
expect(page).to have_content("Question in English")
|
||||||
|
|
||||||
|
select('Español', from: 'locale-switcher')
|
||||||
|
expect(page).to have_content("Pregunta correcta en Español")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Remove a translation", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
click_link "Español"
|
||||||
|
click_link "Remove language"
|
||||||
|
|
||||||
|
expect(page).not_to have_link "Español"
|
||||||
|
|
||||||
|
click_button "Save"
|
||||||
|
visit @edit_question_url
|
||||||
|
expect(page).not_to have_link "Español"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Globalize javascript interface" do
|
||||||
|
|
||||||
|
scenario "Highlight current locale", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
expect(find("a.js-globalize-locale-link.is-active")).to have_content "English"
|
||||||
|
|
||||||
|
select('Español', from: 'locale-switcher')
|
||||||
|
|
||||||
|
expect(find("a.js-globalize-locale-link.is-active")).to have_content "Español"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Highlight selected locale", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
expect(find("a.js-globalize-locale-link.is-active")).to have_content "English"
|
||||||
|
|
||||||
|
click_link "Español"
|
||||||
|
|
||||||
|
expect(find("a.js-globalize-locale-link.is-active")).to have_content "Español"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Show selected locale form", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
expect(page).to have_field('poll_question_title_en', with: 'Question in English')
|
||||||
|
|
||||||
|
click_link "Español"
|
||||||
|
|
||||||
|
expect(page).to have_field('poll_question_title_es', with: 'Pregunta en Español')
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Select a locale and add it to the poll form", :js do
|
||||||
|
visit @edit_question_url
|
||||||
|
|
||||||
|
select "Français", from: "translation_locale"
|
||||||
|
|
||||||
|
expect(page).to have_link "Français"
|
||||||
|
|
||||||
|
click_link "Français"
|
||||||
|
|
||||||
|
expect(page).to have_field('poll_question_title_fr')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user