Use PostgreSQL inheritance for blocks and mutes (#2520)

This commit is contained in:
Akihiko Odaki 2017-04-30 07:27:31 +09:00 committed by Eugen Rochko
parent f48cb3eb17
commit 5135d609b7
7 changed files with 43 additions and 12 deletions

View file

@ -87,11 +87,11 @@ class Account < ApplicationRecord
end end
def block!(other_account) def block!(other_account)
block_relationships.where(target_account: other_account).first_or_create!(target_account: other_account) block_relationships.where(target_account: other_account).first_or_create!(target_account: other_account, block: true)
end end
def mute!(other_account) def mute!(other_account)
mute_relationships.where(target_account: other_account).first_or_create!(target_account: other_account) mute_relationships.where(target_account: other_account).first_or_create!(target_account: other_account, block: false)
end end
def unfollow!(other_account) def unfollow!(other_account)

View file

@ -0,0 +1,19 @@
class CreateBlockMutes < ActiveRecord::Migration[5.0]
def change
create_table "block_mutes", force: :casecade do |t|
t.integer "account_id", null: false
t.integer "target_account_id", null: false
t.boolean "block", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_column :blocks, :block, :boolean, null: false
execute "ALTER TABLE blocks ADD CONSTRAINT check_mutes_on_block CHECK(block = TRUE), INHERIT block_mutes"
Block.update_all block: true
add_column :mutes, :block, :boolean, null: false
execute "ALTER TABLE mutes ADD CONSTRAINT check_mutes_on_block CHECK(block = FALSE), INHERIT block_mutes"
Mute.update_all block: false
end
end

View file

@ -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: 20170425202925) do ActiveRecord::Schema.define(version: 20180428000000) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -54,13 +54,23 @@ ActiveRecord::Schema.define(version: 20170425202925) do
t.index ["username", "domain"], name: "index_accounts_on_username_and_domain", unique: true, using: :btree t.index ["username", "domain"], name: "index_accounts_on_username_and_domain", unique: true, using: :btree
end end
create_table "block_mutes", force: :cascade, id: false do |t|
t.integer "account_id", null: false
t.integer "target_account_id", null: false
t.boolean "block", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "blocks", force: :cascade do |t| create_table "blocks", force: :cascade do |t|
t.integer "account_id", null: false t.integer "account_id", null: false
t.integer "target_account_id", null: false t.integer "target_account_id", null: false
t.boolean "block", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["account_id", "target_account_id"], name: "index_blocks_on_account_id_and_target_account_id", unique: true, using: :btree t.index ["account_id", "target_account_id"], name: "index_blocks_on_account_id_and_target_account_id", unique: true, using: :btree
end end
execute "ALTER TABLE blocks ADD CONSTRAINT check_blocks_on_block CHECK(block = TRUE), INHERIT block_mutes"
create_table "domain_blocks", force: :cascade do |t| create_table "domain_blocks", force: :cascade do |t|
t.string "domain", default: "", null: false t.string "domain", default: "", null: false
@ -137,10 +147,12 @@ ActiveRecord::Schema.define(version: 20170425202925) do
create_table "mutes", force: :cascade do |t| create_table "mutes", force: :cascade do |t|
t.integer "account_id", null: false t.integer "account_id", null: false
t.integer "target_account_id", null: false t.integer "target_account_id", null: false
t.boolean "block", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["account_id", "target_account_id"], name: "index_mutes_on_account_id_and_target_account_id", unique: true, using: :btree t.index ["account_id", "target_account_id"], name: "index_mutes_on_account_id_and_target_account_id", unique: true, using: :btree
end end
execute "ALTER TABLE mutes ADD CONSTRAINT check_mutes_on_block CHECK(block = FALSE), INHERIT block_mutes"
create_table "notifications", force: :cascade do |t| create_table "notifications", force: :cascade do |t|
t.integer "account_id" t.integer "account_id"

View file

@ -152,7 +152,7 @@ RSpec.describe AtomSerializer do
describe '#block_salmon' do describe '#block_salmon' do
let(:xml) do let(:xml) do
block = Fabricate(:block, account: author, target_account: receiver) block = Fabricate(:block, account: author, target_account: receiver, block: true)
xml = AtomSerializer.render(AtomSerializer.new.block_salmon(block)) xml = AtomSerializer.render(AtomSerializer.new.block_salmon(block))
block.destroy block.destroy
xml xml
@ -171,7 +171,7 @@ RSpec.describe AtomSerializer do
describe '#unblock_salmon' do describe '#unblock_salmon' do
let(:xml) do let(:xml) do
block = Fabricate(:block, account: author, target_account: receiver) block = Fabricate(:block, account: author, target_account: receiver, block: true)
block.destroy block.destroy
xml = AtomSerializer.render(AtomSerializer.new.unblock_salmon(block)) xml = AtomSerializer.render(AtomSerializer.new.unblock_salmon(block))
author.block!(receiver) author.block!(receiver)

View file

@ -193,9 +193,9 @@ RSpec.describe Account, type: :model do
describe '#excluded_from_timeline_account_ids' do describe '#excluded_from_timeline_account_ids' do
it 'includes account ids of blockings, blocked_bys and mutes' do it 'includes account ids of blockings, blocked_bys and mutes' do
account = Fabricate(:account) account = Fabricate(:account)
block = Fabricate(:block, account: account) block = Fabricate(:block, account: account, block: true)
mute = Fabricate(:mute, account: account) mute = Fabricate(:mute, account: account, block: false)
block_by = Fabricate(:block, target_account: account) block_by = Fabricate(:block, target_account: account, block: true)
results = account.excluded_from_timeline_account_ids results = account.excluded_from_timeline_account_ids
expect(results.size).to eq 3 expect(results.size).to eq 3

View file

@ -226,7 +226,7 @@ RSpec.describe Status, type: :model do
it 'excludes statuses from accounts blocked by the account' do it 'excludes statuses from accounts blocked by the account' do
blocked = Fabricate(:account) blocked = Fabricate(:account)
Fabricate(:block, account: @account, target_account: blocked) Fabricate(:block, account: @account, target_account: blocked, block: true)
blocked_status = Fabricate(:status, account: blocked) blocked_status = Fabricate(:status, account: blocked)
results = Status.as_public_timeline(@account) results = Status.as_public_timeline(@account)
@ -235,7 +235,7 @@ RSpec.describe Status, type: :model do
it 'excludes statuses from accounts who have blocked the account' do it 'excludes statuses from accounts who have blocked the account' do
blocked = Fabricate(:account) blocked = Fabricate(:account)
Fabricate(:block, account: blocked, target_account: @account) Fabricate(:block, account: blocked, target_account: @account, block: true)
blocked_status = Fabricate(:status, account: blocked) blocked_status = Fabricate(:status, account: blocked)
results = Status.as_public_timeline(@account) results = Status.as_public_timeline(@account)
@ -244,7 +244,7 @@ RSpec.describe Status, type: :model do
it 'excludes statuses from accounts muted by the account' do it 'excludes statuses from accounts muted by the account' do
muted = Fabricate(:account) muted = Fabricate(:account)
Fabricate(:mute, account: @account, target_account: muted) Fabricate(:mute, account: @account, target_account: muted, block: false)
muted_status = Fabricate(:status, account: muted) muted_status = Fabricate(:status, account: muted)
results = Status.as_public_timeline(@account) results = Status.as_public_timeline(@account)

View file

@ -188,7 +188,7 @@ if (cluster.isMaster) {
const unpackedPayload = JSON.parse(payload) const unpackedPayload = JSON.parse(payload)
const targetAccountIds = [unpackedPayload.account.id].concat(unpackedPayload.mentions.map(item => item.id)).concat(unpackedPayload.reblog ? [unpackedPayload.reblog.account.id] : []) const targetAccountIds = [unpackedPayload.account.id].concat(unpackedPayload.mentions.map(item => item.id)).concat(unpackedPayload.reblog ? [unpackedPayload.reblog.account.id] : [])
client.query(`SELECT target_account_id FROM blocks WHERE account_id = $1 AND target_account_id IN (${placeholders(targetAccountIds, 1)}) UNION SELECT target_account_id FROM mutes WHERE account_id = $1 AND target_account_id IN (${placeholders(targetAccountIds, 1)})`, [req.accountId].concat(targetAccountIds), (err, result) => { client.query(`SELECT target_account_id FROM block_mutes WHERE account_id = $1 AND target_account_id IN (${placeholders(targetAccountIds, 1)})`, [req.accountId].concat(targetAccountIds), (err, result) => {
done() done()
if (err) { if (err) {