mirror of
https://github.com/projekteuler/projekteuler.git
synced 2025-12-10 00:36:42 +01:00
Show author names in problem and translation views
This commit is contained in:
parent
ddb1cfac33
commit
89a8fbba99
@ -13,6 +13,9 @@ class TranslationsController < ApplicationController
|
|||||||
# POST /translations
|
# POST /translations
|
||||||
def create
|
def create
|
||||||
@translation = @problem.translations.new(translation_params)
|
@translation = @problem.translations.new(translation_params)
|
||||||
|
if user_signed_in?
|
||||||
|
@translation.author = current_user
|
||||||
|
end
|
||||||
if @translation.save
|
if @translation.save
|
||||||
redirect_to @problem, notice: t('translations.notice.successfully_created')
|
redirect_to @problem, notice: t('translations.notice.successfully_created')
|
||||||
else
|
else
|
||||||
|
|||||||
@ -4,7 +4,8 @@ class Problem < ApplicationRecord
|
|||||||
delegate :title, :content, to: :translation
|
delegate :title, :content, to: :translation
|
||||||
|
|
||||||
has_many :translations, inverse_of: :problem
|
has_many :translations, inverse_of: :problem
|
||||||
|
has_many :authors, -> { where(translations: { status: [:in_use, :outdated] }).distinct }, through: :translations
|
||||||
|
|
||||||
self.per_page = 50
|
self.per_page = 50
|
||||||
|
|
||||||
def is_translated?
|
def is_translated?
|
||||||
@ -19,6 +20,10 @@ class Problem < ApplicationRecord
|
|||||||
self.translation.in_use!
|
self.translation.in_use!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_anonymous_author?
|
||||||
|
translations.where(status: [:in_use, :outdated], author: nil).any?
|
||||||
|
end
|
||||||
|
|
||||||
def original_url
|
def original_url
|
||||||
"https://projecteuler.net/problem=#{self.id}"
|
"https://projecteuler.net/problem=#{self.id}"
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
class Translation < ApplicationRecord
|
class Translation < ApplicationRecord
|
||||||
belongs_to :problem, inverse_of: :translations
|
belongs_to :problem, inverse_of: :translations
|
||||||
|
belongs_to :author, class_name: 'User', inverse_of: :translations, optional: true
|
||||||
enum status: [:pending, :in_use, :outdated, :declined]
|
enum status: [:pending, :in_use, :outdated, :declined]
|
||||||
|
|
||||||
validates :title, :content, :problem_id, presence: true
|
validates :title, :content, :problem_id, presence: true
|
||||||
@ -7,6 +8,10 @@ class Translation < ApplicationRecord
|
|||||||
|
|
||||||
self.per_page = 50
|
self.per_page = 50
|
||||||
|
|
||||||
|
def has_author?
|
||||||
|
!!self.author
|
||||||
|
end
|
||||||
|
|
||||||
def title_is_unique_among_other_problems
|
def title_is_unique_among_other_problems
|
||||||
Problem.includes(:translation).where.not(id: problem_id).each do |problem|
|
Problem.includes(:translation).where.not(id: problem_id).each do |problem|
|
||||||
if problem.is_translated? and problem.title == title
|
if problem.is_translated? and problem.title == title
|
||||||
|
|||||||
@ -2,6 +2,7 @@ class User < ApplicationRecord
|
|||||||
devise :omniauthable, :rememberable
|
devise :omniauthable, :rememberable
|
||||||
|
|
||||||
enum role: [:user, :admin]
|
enum role: [:user, :admin]
|
||||||
|
has_many :translations, inverse_of: :author, dependent: :nullify
|
||||||
|
|
||||||
def self.from_omniauth(auth)
|
def self.from_omniauth(auth)
|
||||||
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
|
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th><%= Translation.human_attribute_name(:created_at) %></th>
|
<th><%= Translation.human_attribute_name(:created_at) %></th>
|
||||||
|
<th><%= Translation.human_attribute_name(:author) %></th>
|
||||||
<th><%= Translation.human_attribute_name(:problem_id) %></th>
|
<th><%= Translation.human_attribute_name(:problem_id) %></th>
|
||||||
<th><%= Translation.human_attribute_name(:title) %></th>
|
<th><%= Translation.human_attribute_name(:title) %></th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -16,6 +17,13 @@
|
|||||||
<% @translations.each do |translation| %>
|
<% @translations.each do |translation| %>
|
||||||
<tr>
|
<tr>
|
||||||
<td><div data-toggle="tooltip" data-placement="left" title="<%= l translation.created_at %>"><%= time_ago_in_words(translation.created_at) %></div></td>
|
<td><div data-toggle="tooltip" data-placement="left" title="<%= l translation.created_at %>"><%= time_ago_in_words(translation.created_at) %></div></td>
|
||||||
|
<td>
|
||||||
|
<% if translation.has_author? %>
|
||||||
|
<%= translation.author.name %>
|
||||||
|
<% else %>
|
||||||
|
<i><%= t('.anonymous') %></i>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
<td><%= translation.problem_id %></td>
|
<td><%= translation.problem_id %></td>
|
||||||
<td><%= link_to translation.title, [:admin, translation] %></td>
|
<td><%= link_to translation.title, [:admin, translation] %></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
<% provide(:title, t('problems.show.problem_subtitle', id: @translation.problem_id)) %>
|
<% provide(:title, t('problems.show.problem_subtitle', id: @translation.problem_id)) %>
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
|
<p class="text-muted">
|
||||||
|
<%= render 'shared/authors', authors: Array(@translation.author) %>
|
||||||
|
</p>
|
||||||
<h1><%= @translation.title %> <small><%= t 'problems.show.problem_subtitle', id: @translation.problem_id %></small></h1>
|
<h1><%= @translation.title %> <small><%= t 'problems.show.problem_subtitle', id: @translation.problem_id %></small></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
<% provide(:title, t('problems.show.problem_subtitle', id: @problem.id)) %>
|
<% provide(:title, t('problems.show.problem_subtitle', id: @problem.id)) %>
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
|
<p class="text-muted">
|
||||||
|
<%= render 'shared/authors', authors: @problem.authors, has_anonymous_author: @problem.has_anonymous_author? %>
|
||||||
|
</p>
|
||||||
<h1><%= @problem.title %> <small><%= t '.problem_subtitle', id: @problem.id %></small></h1>
|
<h1><%= @problem.title %> <small><%= t '.problem_subtitle', id: @problem.id %></small></h1>
|
||||||
</div>
|
</div>
|
||||||
<%= link_to new_problem_translation_path(@problem), class: 'btn btn-default btn-sm pull-right' do %>
|
<%= link_to new_problem_translation_path(@problem), class: 'btn btn-default btn-sm pull-right' do %>
|
||||||
|
|||||||
11
app/views/shared/_authors.de.html.erb
Normal file
11
app/views/shared/_authors.de.html.erb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<% if authors.empty? %>
|
||||||
|
Diese Übersetung wurde anonym erstellt.
|
||||||
|
<% else %>
|
||||||
|
Diese Übersetzung wurde von
|
||||||
|
<% if local_assigns[:has_anonymous_author] %>
|
||||||
|
<%= (authors.map(&:name)+Array("anonymen Nutzern")).to_sentence %>
|
||||||
|
<% else %>
|
||||||
|
<%= authors.map(&:name).to_sentence %>
|
||||||
|
<% end %>
|
||||||
|
erstellt.
|
||||||
|
<% end %>
|
||||||
@ -11,4 +11,5 @@ de:
|
|||||||
id: ID
|
id: ID
|
||||||
problem_id: Problem-ID
|
problem_id: Problem-ID
|
||||||
title: Titel
|
title: Titel
|
||||||
content: Inhalt
|
content: Inhalt
|
||||||
|
author: Autor
|
||||||
@ -11,6 +11,8 @@ de:
|
|||||||
failure_message: "Problem-Anzahl konnte nicht aktualisiert werden! Grund: %{error}"
|
failure_message: "Problem-Anzahl konnte nicht aktualisiert werden! Grund: %{error}"
|
||||||
no_problem_count: "Keine Problem-Anzahl gegeben!"
|
no_problem_count: "Keine Problem-Anzahl gegeben!"
|
||||||
translations:
|
translations:
|
||||||
|
index:
|
||||||
|
anonymous: "Anonym"
|
||||||
must_be_pending: "Übersetzung muss ausstehend sein, um akzeptiert oder abgelehnt zu werden!"
|
must_be_pending: "Übersetzung muss ausstehend sein, um akzeptiert oder abgelehnt zu werden!"
|
||||||
show:
|
show:
|
||||||
accept_translation: "Akzeptieren"
|
accept_translation: "Akzeptieren"
|
||||||
|
|||||||
5
db/migrate/20190204164033_add_author_to_translations.rb
Normal file
5
db/migrate/20190204164033_add_author_to_translations.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class AddAuthorToTranslations < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_reference :translations, :author, index: true, null: true, foreign_key: {to_table: :users}
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2019_02_03_164629) do
|
ActiveRecord::Schema.define(version: 2019_02_04_164033) do
|
||||||
|
|
||||||
create_table "problems", force: :cascade do |t|
|
create_table "problems", force: :cascade do |t|
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
@ -26,6 +26,8 @@ ActiveRecord::Schema.define(version: 2019_02_03_164629) do
|
|||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.integer "problem_id"
|
t.integer "problem_id"
|
||||||
t.integer "status", default: 0
|
t.integer "status", default: 0
|
||||||
|
t.integer "author_id"
|
||||||
|
t.index ["author_id"], name: "index_translations_on_author_id"
|
||||||
t.index ["problem_id"], name: "index_translations_on_problem_id"
|
t.index ["problem_id"], name: "index_translations_on_problem_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class TranslationsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should create translation" do
|
test "should create translation anonymously" do
|
||||||
assert_difference('Translation.count') do
|
assert_difference('Translation.count') do
|
||||||
post problem_translations_url(problem_id: 1, translation: @update)
|
post problem_translations_url(problem_id: 1, translation: @update)
|
||||||
end
|
end
|
||||||
@ -30,6 +30,16 @@ class TranslationsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
assert_redirected_to problem_path(id: 1)
|
assert_redirected_to problem_path(id: 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "should create translation with user" do
|
||||||
|
login_translator
|
||||||
|
assert_difference('Translation.count') do
|
||||||
|
post problem_translations_url(problem_id: 1, translation: @update)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_redirected_to problem_path(id: 1)
|
||||||
|
assert_equal users(:translator), Translation.last.author
|
||||||
|
end
|
||||||
|
|
||||||
test "should not create incorrect translation" do
|
test "should not create incorrect translation" do
|
||||||
assert_no_difference('Translation.count') do
|
assert_no_difference('Translation.count') do
|
||||||
post problem_translations_url(problem_id: 1, translation: @incorrect)
|
post problem_translations_url(problem_id: 1, translation: @incorrect)
|
||||||
|
|||||||
@ -10,6 +10,12 @@ class ActiveSupport::TestCase
|
|||||||
fixtures :all
|
fixtures :all
|
||||||
|
|
||||||
# Add more helper methods to be used by all tests here...
|
# Add more helper methods to be used by all tests here...
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class ActionDispatch::IntegrationTest
|
||||||
|
include Devise::Test::IntegrationHelpers
|
||||||
|
|
||||||
def login_admin
|
def login_admin
|
||||||
admin = users(:admin)
|
admin = users(:admin)
|
||||||
sign_in admin
|
sign_in admin
|
||||||
@ -19,10 +25,7 @@ class ActiveSupport::TestCase
|
|||||||
translator = users(:translator)
|
translator = users(:translator)
|
||||||
sign_in translator
|
sign_in translator
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
class ActionDispatch::IntegrationTest
|
|
||||||
OmniAuth.config.test_mode = true
|
OmniAuth.config.test_mode = true
|
||||||
OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new({
|
OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new({
|
||||||
provider: :github,
|
provider: :github,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user