Create share visibilities for photos attached to a private post
Also fixed the "fix public photos"-migration, because it didn't work with migration-models :/ fixes #6177
This commit is contained in:
parent
78083afe38
commit
3f2586bc6f
7 changed files with 101 additions and 25 deletions
|
|
@ -10,6 +10,10 @@ class ShareVisibility < ActiveRecord::Base
|
||||||
where(user_id: user.id)
|
where(user_id: user.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope :for_shareable, ->(shareable) {
|
||||||
|
where(shareable_id: shareable.id, shareable_type: shareable.class.base_class.to_s)
|
||||||
|
}
|
||||||
|
|
||||||
validate :not_public
|
validate :not_public
|
||||||
|
|
||||||
# Perform a batch import, given a set of users and a shareable
|
# Perform a batch import, given a set of users and a shareable
|
||||||
|
|
@ -18,8 +22,17 @@ class ShareVisibility < ActiveRecord::Base
|
||||||
# @param share [Shareable]
|
# @param share [Shareable]
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def self.batch_import(user_ids, share)
|
def self.batch_import(user_ids, share)
|
||||||
return false unless ShareVisibility.new(shareable_id: share.id, shareable_type: share.class.to_s).valid?
|
return false unless ShareVisibility.new(shareable_id: share.id, shareable_type: share.class.base_class.to_s).valid?
|
||||||
|
|
||||||
|
user_ids -= ShareVisibility.for_shareable(share).where(user_id: user_ids).pluck(:user_id)
|
||||||
|
return false if user_ids.empty?
|
||||||
|
|
||||||
|
create_visilities(user_ids, share)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
private_class_method def self.create_visilities(user_ids, share)
|
||||||
if AppConfig.postgres?
|
if AppConfig.postgres?
|
||||||
user_ids.each do |user_id|
|
user_ids.each do |user_id|
|
||||||
ShareVisibility.find_or_create_by(
|
ShareVisibility.find_or_create_by(
|
||||||
|
|
@ -36,8 +49,6 @@ class ShareVisibility < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def not_public
|
def not_public
|
||||||
errors[:base] << "Cannot create visibility for a public object" if shareable.public?
|
errors[:base] << "Cannot create visibility for a public object" if shareable.public?
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,12 @@ class StatusMessage < Post
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def receive(recipient_user_ids)
|
||||||
|
super(recipient_user_ids)
|
||||||
|
|
||||||
|
photos.each {|photo| photo.receive(recipient_user_ids) }
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def presence_of_content
|
def presence_of_content
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,4 @@
|
||||||
class CleanupDuplicatesAndAddUniqueIndexes < ActiveRecord::Migration
|
class CleanupDuplicatesAndAddUniqueIndexes < ActiveRecord::Migration
|
||||||
class Post < ActiveRecord::Base
|
|
||||||
end
|
|
||||||
|
|
||||||
class StatusMessage < Post
|
|
||||||
end
|
|
||||||
|
|
||||||
class Photo < ActiveRecord::Base
|
|
||||||
belongs_to :status_message, foreign_key: :status_message_guid, primary_key: :guid
|
|
||||||
end
|
|
||||||
|
|
||||||
class ShareVisibility < ActiveRecord::Base
|
|
||||||
end
|
|
||||||
|
|
||||||
def up
|
def up
|
||||||
# temporary index to speed up the migration
|
# temporary index to speed up the migration
|
||||||
add_index :photos, :guid, length: 191
|
add_index :photos, :guid, length: 191
|
||||||
|
|
@ -34,12 +21,6 @@ class CleanupDuplicatesAndAddUniqueIndexes < ActiveRecord::Migration
|
||||||
%i(conversations messages photos polls poll_answers poll_participations).each do |table|
|
%i(conversations messages photos polls poll_answers poll_participations).each do |table|
|
||||||
delete_duplicates_and_create_unique_index(table)
|
delete_duplicates_and_create_unique_index(table)
|
||||||
end
|
end
|
||||||
|
|
||||||
# fix photo public flag again ...
|
|
||||||
Photo.joins(:status_message).where(posts: {public: true}).update_all(public: true)
|
|
||||||
|
|
||||||
ShareVisibility.joins("INNER JOIN photos ON photos.id = share_visibilities.shareable_id")
|
|
||||||
.where(shareable_type: "Photo", photos: {public: true}).delete_all
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
|
|
|
||||||
42
db/migrate/20160906225138_fix_photos_share_visibilities.rb
Normal file
42
db/migrate/20160906225138_fix_photos_share_visibilities.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
class FixPhotosShareVisibilities < ActiveRecord::Migration
|
||||||
|
class Photo < ActiveRecord::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
class ShareVisibility < ActiveRecord::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
def up
|
||||||
|
Photo.joins("INNER JOIN posts ON posts.guid = photos.status_message_guid")
|
||||||
|
.where(posts: {type: "StatusMessage", public: true}).update_all(public: true)
|
||||||
|
|
||||||
|
ShareVisibility.joins("INNER JOIN photos ON photos.id = share_visibilities.shareable_id")
|
||||||
|
.where(shareable_type: "Photo", photos: {public: true}).delete_all
|
||||||
|
|
||||||
|
remove_duplicates
|
||||||
|
remove_index :share_visibilities, name: :shareable_and_user_id
|
||||||
|
add_index :share_visibilities, %i(shareable_id shareable_type user_id), name: :shareable_and_user_id, unique: true
|
||||||
|
|
||||||
|
execute "INSERT INTO share_visibilities (user_id, shareable_id, shareable_type) " \
|
||||||
|
"SELECT post_visibility.user_id, photos.id, 'Photo' FROM photos " \
|
||||||
|
"INNER JOIN posts ON posts.guid = photos.status_message_guid AND posts.type = 'StatusMessage' " \
|
||||||
|
"LEFT OUTER JOIN share_visibilities ON share_visibilities.shareable_id = photos.id " \
|
||||||
|
"INNER JOIN share_visibilities AS post_visibility ON post_visibility.shareable_id = posts.id " \
|
||||||
|
"WHERE photos.public = 0 AND share_visibilities.shareable_id IS NULL " \
|
||||||
|
"AND post_visibility.shareable_type = 'Post'"
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_index :share_visibilities, name: :shareable_and_user_id
|
||||||
|
add_index :share_visibilities, %i(shareable_id shareable_type user_id), name: :shareable_and_user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_duplicates
|
||||||
|
where = "WHERE s1.user_id = s2.user_id AND s1.shareable_id = s2.shareable_id AND "\
|
||||||
|
"s1.shareable_type = s2.shareable_type AND s1.id > s2.id"
|
||||||
|
if AppConfig.postgres?
|
||||||
|
execute("DELETE FROM share_visibilities AS s1 USING share_visibilities AS s2 #{where}")
|
||||||
|
else
|
||||||
|
execute("DELETE s1 FROM share_visibilities s1, share_visibilities s2 #{where}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -11,7 +11,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: 20160902180630) do
|
ActiveRecord::Schema.define(version: 20160906225138) do
|
||||||
|
|
||||||
create_table "account_deletions", force: :cascade do |t|
|
create_table "account_deletions", force: :cascade do |t|
|
||||||
t.string "diaspora_handle", limit: 255
|
t.string "diaspora_handle", limit: 255
|
||||||
|
|
@ -538,7 +538,7 @@ ActiveRecord::Schema.define(version: 20160902180630) do
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "user_id"], name: "shareable_and_hidden_and_user_id", using: :btree
|
add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "user_id"], name: "shareable_and_hidden_and_user_id", using: :btree
|
||||||
add_index "share_visibilities", ["shareable_id", "shareable_type", "user_id"], name: "shareable_and_user_id", using: :btree
|
add_index "share_visibilities", ["shareable_id", "shareable_type", "user_id"], name: "shareable_and_user_id", unique: true, using: :btree
|
||||||
add_index "share_visibilities", ["shareable_id"], name: "index_post_visibilities_on_post_id", using: :btree
|
add_index "share_visibilities", ["shareable_id"], name: "index_post_visibilities_on_post_id", using: :btree
|
||||||
add_index "share_visibilities", ["user_id"], name: "index_share_visibilities_on_user_id", using: :btree
|
add_index "share_visibilities", ["user_id"], name: "index_share_visibilities_on_user_id", using: :btree
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
describe ShareVisibility, :type => :model do
|
describe ShareVisibility, type: :model do
|
||||||
describe ".batch_import" do
|
describe ".batch_import" do
|
||||||
let(:post) { FactoryGirl.create(:status_message, author: alice.person) }
|
let(:post) { FactoryGirl.create(:status_message, author: alice.person) }
|
||||||
|
|
||||||
|
|
@ -29,6 +29,13 @@ describe ShareVisibility, :type => :model do
|
||||||
}.not_to raise_error
|
}.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not create visibilities for a public shareable" do
|
||||||
|
public_post = FactoryGirl.create(:status_message, author: alice.person, public: true)
|
||||||
|
|
||||||
|
ShareVisibility.batch_import([bob.id], public_post)
|
||||||
|
expect(ShareVisibility.where(user_id: bob.id, shareable_id: post.id, shareable_type: "Post")).not_to exist
|
||||||
|
end
|
||||||
|
|
||||||
context "scopes" do
|
context "scopes" do
|
||||||
before do
|
before do
|
||||||
alice.post(:status_message, text: "Hey", to: alice.aspects.first)
|
alice.post(:status_message, text: "Hey", to: alice.aspects.first)
|
||||||
|
|
|
||||||
|
|
@ -302,4 +302,33 @@ describe StatusMessage, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#receive" do
|
||||||
|
let(:post) { FactoryGirl.create(:status_message, author: alice.person) }
|
||||||
|
|
||||||
|
it "receives attached photos" do
|
||||||
|
photo = FactoryGirl.create(:photo, status_message: post)
|
||||||
|
|
||||||
|
post.receive([bob.id])
|
||||||
|
|
||||||
|
expect(ShareVisibility.where(user_id: bob.id, shareable_id: post.id, shareable_type: "Post").count).to eq(1)
|
||||||
|
expect(ShareVisibility.where(user_id: bob.id, shareable_id: photo.id, shareable_type: "Photo").count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "works without attached photos" do
|
||||||
|
post.receive([bob.id])
|
||||||
|
|
||||||
|
expect(ShareVisibility.where(user_id: bob.id, shareable_id: post.id, shareable_type: "Post").count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "works with already received attached photos" do
|
||||||
|
photo = FactoryGirl.create(:photo, status_message: post)
|
||||||
|
|
||||||
|
photo.receive([bob.id])
|
||||||
|
post.receive([bob.id])
|
||||||
|
|
||||||
|
expect(ShareVisibility.where(user_id: bob.id, shareable_id: post.id, shareable_type: "Post").count).to eq(1)
|
||||||
|
expect(ShareVisibility.where(user_id: bob.id, shareable_id: photo.id, shareable_type: "Photo").count).to eq(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue