103 行
2.8 KiB
Ruby
103 行
2.8 KiB
Ruby
class GekanatorQuestionsController < ApplicationController
|
|
def index
|
|
questions =
|
|
GekanatorQuestion
|
|
.accepted
|
|
.includes(:gekanator_question_examples)
|
|
.order(priority_weight: :desc, id: :asc)
|
|
|
|
render json: {
|
|
questions: questions.map { |question| question_json(question) }
|
|
}
|
|
end
|
|
|
|
private
|
|
|
|
def question_json question
|
|
condition = condition_json(question.condition).deep_symbolize_keys
|
|
json = {
|
|
id: question_id_for(question, condition),
|
|
text: question_text_for(question, condition),
|
|
kind: question.kind,
|
|
condition: condition,
|
|
source: question.source,
|
|
priority_weight: question.priority_weight
|
|
}
|
|
if question.kind == 'post_similarity'
|
|
json[:example_answers] = example_answers_json(question)
|
|
end
|
|
json
|
|
end
|
|
|
|
def question_id_for question, condition
|
|
case condition[:type]
|
|
when 'tag'
|
|
"tag:#{ condition[:key] }"
|
|
when 'source'
|
|
"source:#{ condition[:host] }"
|
|
when 'original-year'
|
|
"original-year:#{ condition[:year] }"
|
|
when 'original-month'
|
|
"original-month:#{ condition[:month] }"
|
|
when 'original-month-day'
|
|
"original-month-day:#{ condition[:monthDay] || condition[:month_day] }"
|
|
when 'title-length-at-least'
|
|
"title:length-at-least:#{ condition[:length] }"
|
|
when 'title-length-greater-than'
|
|
"title:length-at-least:#{ condition[:length].to_i + 1 }"
|
|
when 'title-has-ascii'
|
|
'title:ascii'
|
|
when 'title-contains'
|
|
"title:contains:#{ condition[:text] }"
|
|
when 'post-similarity'
|
|
"post-similarity:#{ question.id }"
|
|
else
|
|
"catalog:#{ question.id }"
|
|
end
|
|
end
|
|
|
|
def condition_json condition
|
|
json = condition.deep_dup.as_json
|
|
|
|
if json['type'] == 'original-month-day' && json['monthDay'].blank?
|
|
json['monthDay'] = json.delete('month_day')
|
|
end
|
|
|
|
if json['type'] == 'title-length-greater-than'
|
|
json['type'] = 'title-length-at-least'
|
|
json['length'] = json['length'].to_i + 1
|
|
end
|
|
|
|
json
|
|
end
|
|
|
|
def question_text_for question, condition
|
|
return question.text unless question.kind == 'title'
|
|
|
|
case condition[:type]
|
|
when 'title-length-at-least'
|
|
"タイトルは #{ condition[:length] } 文字以上?"
|
|
when 'title-contains'
|
|
"題名に「#{ condition[:text] }」が含まれる?"
|
|
else
|
|
question.text
|
|
end
|
|
end
|
|
|
|
def example_answers_json question
|
|
question
|
|
.gekanator_question_examples
|
|
.group_by(&:post_id)
|
|
.transform_values { |examples| aggregate_answer(examples) }
|
|
end
|
|
|
|
def aggregate_answer examples
|
|
examples
|
|
.group_by(&:answer)
|
|
.map { |answer, grouped| [answer, grouped.sum(&:weight), grouped.max_by(&:updated_at)&.updated_at] }
|
|
.sort_by { |(_answer, weight, updated_at)| [-weight, -(updated_at&.to_f || 0)] }
|
|
.first
|
|
&.first
|
|
end
|
|
end
|