[deploy] Add unique index on articles user_id, title and body_markdown (#10284)
* Add unique index on articles user_id, title and body_markdown * Add test
This commit is contained in:
parent
f6e24bc85b
commit
f0b124cc26
4 changed files with 37 additions and 8 deletions
|
|
@ -11,10 +11,3 @@ require:
|
|||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/UniqueValidationWithoutIndex:
|
||||
Exclude:
|
||||
- 'app/models/article.rb'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
class AddUniqueIndexToArticlesUserIdTitleBodyMarkdown < ActiveRecord::Migration[6.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
# to avoid the error "Values larger than 1/3 of a buffer page cannot be indexed."
|
||||
# due to the fact that large text column cannot be indexed by btree indexes
|
||||
# we are going to need to build an index on the hash of the `body_markdown` column.
|
||||
# We also cannot use a `HASH` index as it's not supported by unique columns.
|
||||
# I don't recommend using GiN or GiST as well
|
||||
# See <https://www.postgresql.org/message-id/AANLkTin3p6VS1Z=TtqUV-5cG4TZpTjUMfuPNzWJFgnr5@mail.gmail.com>,
|
||||
# <https://www.postgresql.org/docs/11/pgcrypto.html#id-1.11.7.34.5> and
|
||||
# <https://www.postgresql.org/docs/11/indexes-types.html>
|
||||
# NOTE: using SQL as I couldn't find a way to have Rails generate it correctly
|
||||
ActiveRecord::Base.connection.execute(
|
||||
<<~SQL
|
||||
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "index_articles_on_user_id_and_title_and_digest_body_markdown"
|
||||
ON "articles"
|
||||
USING btree ("user_id", "title", digest("body_markdown", 'sha512'::text));
|
||||
SQL
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_index :articles, name: :index_articles_on_user_id_and_title_and_digest_body_markdown, algorithm: :concurrently
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_09_10_205316) do
|
||||
ActiveRecord::Schema.define(version: 2020_09_11_140318) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "citext"
|
||||
|
|
@ -153,6 +153,7 @@ ActiveRecord::Schema.define(version: 2020_09_10_205316) do
|
|||
t.string "video_source_url"
|
||||
t.string "video_state"
|
||||
t.string "video_thumbnail_url"
|
||||
t.index "user_id, title, digest(body_markdown, 'sha512'::text)", name: "index_articles_on_user_id_and_title_and_digest_body_markdown", unique: true
|
||||
t.index ["boost_states"], name: "index_articles_on_boost_states", using: :gin
|
||||
t.index ["canonical_url"], name: "index_articles_on_canonical_url", unique: true
|
||||
t.index ["comment_score"], name: "index_articles_on_comment_score"
|
||||
|
|
|
|||
|
|
@ -43,6 +43,15 @@ RSpec.describe Article, type: :model do
|
|||
|
||||
it { is_expected.not_to allow_value("foo").for(:main_image_background_hex_color) }
|
||||
|
||||
describe "#body_markdown" do
|
||||
it "is unique scoped for user_id and title" do
|
||||
art2 = build(:article, body_markdown: article.body_markdown, user: article.user, title: article.title)
|
||||
|
||||
expect(art2).not_to be_valid
|
||||
expect(art2.errors.full_messages.to_sentence).to match("markdown has already been taken")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#after_commit" do
|
||||
it "on update enqueues job to index article to elasticsearch" do
|
||||
article.save
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue