TagName サニタイズ(#281) #289
@@ -90,7 +90,7 @@ class WikiPagesController < ApplicationController
|
|||||||
|
|
||||||
return head :unprocessable_entity if name.blank? || body.blank?
|
return head :unprocessable_entity if name.blank? || body.blank?
|
||||||
|
|
||||||
tag_name = TagName.find_or_create_by!(name:)
|
tag_name = TagName.find_undiscard_or_create_by!(name:)
|
||||||
page = WikiPage.new(tag_name:, created_user: current_user, updated_user: current_user)
|
page = WikiPage.new(tag_name:, created_user: current_user, updated_user: current_user)
|
||||||
if page.save
|
if page.save
|
||||||
message = params[:message].presence
|
message = params[:message].presence
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
module MyDiscard
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included { include Discard::Model }
|
||||||
|
|
||||||
|
class_methods do
|
||||||
|
def find_undiscard_or_create_by! attrs, &block
|
||||||
|
record = with_discarded.find_by(attrs)
|
||||||
|
|
||||||
|
if record&.discarded?
|
||||||
|
record.undiscard!
|
||||||
|
record.update_columns(created_at: record.reload.updated_at)
|
||||||
|
end
|
||||||
|
|
||||||
|
record or create!(attrs, &block)
|
||||||
|
rescue ActiveRecord::RecordNotUnique
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
class Tag < ApplicationRecord
|
class Tag < ApplicationRecord
|
||||||
include Discard::Model
|
include MyDiscard
|
||||||
|
|
||||||
class NicoTagNormalisationError < ArgumentError
|
class NicoTagNormalisationError < ArgumentError
|
||||||
;
|
;
|
||||||
@@ -134,10 +134,10 @@ class Tag < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.find_or_create_by_tag_name! name, category:
|
def self.find_or_create_by_tag_name! name, category:
|
||||||
tn = TagName.find_or_create_by!(name: name.to_s.strip)
|
tn = TagName.find_undiscard_or_create_by!(name: name.to_s.strip)
|
||||||
tn = tn.canonical if tn.canonical_id?
|
tn = tn.canonical if tn.canonical_id?
|
||||||
|
|
||||||
Tag.find_or_create_by!(tag_name_id: tn.id) do |t|
|
Tag.find_undiscard_or_create_by!(tag_name_id: tn.id) do |t|
|
||||||
t.category = category
|
t.category = category
|
||||||
end
|
end
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue ActiveRecord::RecordNotUnique
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class TagName < ApplicationRecord
|
class TagName < ApplicationRecord
|
||||||
include Discard::Model
|
include MyDiscard
|
||||||
|
|
||||||
default_scope -> { kept }
|
default_scope -> { kept }
|
||||||
|
|
||||||
@@ -27,10 +27,6 @@ class TagName < ApplicationRecord
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def sanitise_name
|
|
||||||
self.name = TagNameSanitisationRule.sanitise(name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def canonical_must_be_canonical
|
def canonical_must_be_canonical
|
||||||
if canonical&.canonical_id?
|
if canonical&.canonical_id?
|
||||||
errors.add :canonical, 'canonical は実体を示す必要があります.'
|
errors.add :canonical, 'canonical は実体を示す必要があります.'
|
||||||
@@ -50,7 +46,7 @@ class TagName < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def name_must_be_sanitised
|
def name_must_be_sanitised
|
||||||
if name != TagNameSanitisationRule.sanitise(name)
|
if name? && name != TagNameSanitisationRule.sanitise(name)
|
||||||
errors.add :name, '名前に使用できない文字が含まれてゐます.'
|
errors.add :name, '名前に使用できない文字が含まれてゐます.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ require 'set'
|
|||||||
|
|
||||||
|
|
||||||
class WikiPage < ApplicationRecord
|
class WikiPage < ApplicationRecord
|
||||||
include Discard::Model
|
include MyDiscard
|
||||||
|
|
||||||
default_scope -> { kept }
|
default_scope -> { kept }
|
||||||
|
|
||||||
|
|||||||
@@ -525,8 +525,9 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
context "when nico tag already exists in tags" do
|
context "when nico tag already exists in tags" do
|
||||||
before do
|
before do
|
||||||
Tag.find_or_create_by!(tag_name: TagName.find_or_create_by!(name: 'nico:nico_tag'),
|
Tag.find_undiscard_or_create_by!(
|
||||||
category: :nico)
|
tag_name: TagName.find_undiscard_or_create_by!(name: 'nico:nico_tag'),
|
||||||
|
category: :nico)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'return 400' do
|
it 'return 400' do
|
||||||
@@ -610,8 +611,9 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
context "when nico tag already exists in tags" do
|
context "when nico tag already exists in tags" do
|
||||||
before do
|
before do
|
||||||
Tag.find_or_create_by!(tag_name: TagName.find_or_create_by!(name: 'nico:nico_tag'),
|
Tag.find_undiscard_or_create_by!(
|
||||||
category: :nico)
|
tag_name: TagName.find_undiscard_or_create_by!(name: 'nico:nico_tag'),
|
||||||
|
category: :nico)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'return 400' do
|
it 'return 400' do
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ RSpec.describe "nico:sync" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_tag!(name, category:)
|
def create_tag!(name, category:)
|
||||||
tn = TagName.find_or_create_by!(name: name.to_s.strip)
|
tn = TagName.find_undiscard_or_create_by!(name: name.to_s.strip)
|
||||||
Tag.find_or_create_by!(tag_name_id: tn.id) { |t| t.category = category }
|
Tag.find_undiscard_or_create_by!(tag_name_id: tn.id) { |t| t.category = category }
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_nico_to_tag!(nico_tag, tag)
|
def link_nico_to_tag!(nico_tag, tag)
|
||||||
|
|||||||
新しい課題から参照
ユーザをブロックする