Commit 7011f296 authored by Benjamin Neff's avatar Benjamin Neff

Revert "Back out #6723 due to Postgres breakage"

This reverts commit 84cfbd22.
parent 84cfbd22
......@@ -89,6 +89,7 @@ Contributions are very welcome, the hard work is done!
* Stream faces are gone [#6686](https://github.com/diaspora/diaspora/pull/6686)
* Refactor mobile javascript and add tests [#6394](https://github.com/diaspora/diaspora/pull/6394)
* Dropped `parent_author_signature` from relayables [#6586](https://github.com/diaspora/diaspora/pull/6586)
* Attached ShareVisibilities to the User, not the Contact [#6723](https://github.com/diaspora/diaspora/pull/6723)
## Bug fixes
* Destroy Participation when removing interactions with a post [#5852](https://github.com/diaspora/diaspora/pull/5852)
......
......@@ -14,9 +14,6 @@ class Contact < ActiveRecord::Base
has_many :aspect_memberships, :dependent => :destroy
has_many :aspects, :through => :aspect_memberships
has_many :share_visibilities, :source => :shareable, :source_type => 'Post'
has_many :posts, :through => :share_visibilities, :source => :shareable, :source_type => 'Post'
validate :not_contact_for_self,
:not_blocked_user,
:not_contact_with_closed_account
......@@ -60,10 +57,6 @@ class Contact < ActiveRecord::Base
:into => aspects.first)
end
def receive_shareable(shareable)
ShareVisibility.create!(:shareable_id => shareable.id, :shareable_type => shareable.class.base_class.to_s, :contact_id => self.id)
end
def contacts
people = Person.arel_table
incoming_aspects = Aspect.where(
......
......@@ -3,40 +3,36 @@
# the COPYRIGHT file.
class ShareVisibility < ActiveRecord::Base
belongs_to :contact
belongs_to :user
belongs_to :shareable, :polymorphic => :true
scope :for_a_users_contacts, ->(user) {
where(:contact_id => user.contacts.map {|c| c.id})
}
scope :for_contacts_of_a_person, ->(person) {
where(:contact_id => person.contacts.map {|c| c.id})
scope :for_a_user, ->(user) {
where(user_id: user.id)
}
validate :not_public
# Perform a batch import, given a set of contacts and a shareable
# Perform a batch import, given a set of users and a shareable
# @note performs a bulk insert in mySQL; performs linear insertions in postgres
# @param contacts [Array<Contact>] Recipients
# @param user_ids [Array<Integer>] Recipients
# @param share [Shareable]
# @return [void]
def self.batch_import(contact_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?
if AppConfig.postgres?
contact_ids.each do |contact_id|
user_ids.each do |user_id|
ShareVisibility.find_or_create_by(
contact_id: contact_id,
shareable_id: share.id,
user_id: user_id,
shareable_id: share.id,
shareable_type: share.class.base_class.to_s
)
end
else
new_share_visibilities_data = contact_ids.map do |contact_id|
[contact_id, share.id, share.class.base_class.to_s]
new_share_visibilities_data = user_ids.map do |user_id|
[user_id, share.id, share.class.base_class.to_s]
end
ShareVisibility.import([:contact_id, :shareable_id, :shareable_type], new_share_visibilities_data)
ShareVisibility.import(%i(user_id shareable_id shareable_type), new_share_visibilities_data)
end
end
......
......@@ -80,6 +80,8 @@ class User < ActiveRecord::Base
has_many :authorizations, class_name: "Api::OpenidConnect::Authorization"
has_many :o_auth_applications, through: :authorizations, class_name: "Api::OpenidConnect::OAuthApplication"
has_many :share_visibilities
before_save :guard_unconfirmed_email,
:save_person!
......@@ -114,6 +116,10 @@ class User < ActiveRecord::Base
InvitationCode.find_or_create_by(user_id: self.id)
end
def receive_shareable(shareable)
ShareVisibility.create!(shareable_id: shareable.id, shareable_type: shareable.class.base_class.to_s, user_id: id)
end
def hidden_shareables
self[:hidden_shareables] ||= {}
end
......
......@@ -24,23 +24,9 @@ module User::Connecting
end
deliver_profile_update
register_share_visibilities(contact)
contact
end
# This puts the last 100 public posts by the passed in contact into the user's stream.
# @param [Contact] contact
# @return [void]
def register_share_visibilities(contact)
#should have select here, but proven hard to test
posts = Post.where(:author_id => contact.person_id, :public => true).limit(100)
p = posts.map do |post|
ShareVisibility.new(:contact_id => contact.id, :shareable_id => post.id, :shareable_type => 'Post')
end
ShareVisibility.import(p) unless posts.empty?
nil
end
def remove_contact(contact, opts={:force => false, :retracted => false})
if !contact.mutual? || opts[:force]
contact.destroy
......
......@@ -13,90 +13,12 @@ module User::Querying
def visible_shareables(klass, opts={})
opts = prep_opts(klass, opts)
shareable_ids = visible_shareable_ids(klass, opts)
klass.where(:id => shareable_ids).select('DISTINCT '+klass.to_s.tableize+'.*').limit(opts[:limit]).order(opts[:order_with_table]).order(klass.table_name+".id DESC")
klass.where(id: shareable_ids).select("DISTINCT #{klass.table_name}.*")
.limit(opts[:limit]).order(opts[:order_with_table])
end
def visible_shareable_ids(klass, opts={})
opts = prep_opts(klass, opts)
visible_ids_from_sql(klass, opts)
end
# @return [Array<Integer>]
def visible_ids_from_sql(klass, opts={})
opts = prep_opts(klass, opts)
opts[:klass] = klass
opts[:by_members_of] ||= self.aspect_ids
post_ids = klass.connection.select_values(visible_shareable_sql(klass, opts)).map(&:to_i)
post_ids += klass.connection.select_values("#{construct_public_followings_sql(opts).to_sql} LIMIT #{opts[:limit]}").map {|id| id.to_i }
end
def visible_shareable_sql(klass, opts={})
table = klass.table_name
opts = prep_opts(klass, opts)
opts[:klass] = klass
shareable_from_others = construct_shareable_from_others_query(opts)
shareable_from_self = construct_shareable_from_self_query(opts)
"(#{shareable_from_others.to_sql} LIMIT #{opts[:limit]}) UNION ALL (#{shareable_from_self.to_sql} LIMIT #{opts[:limit]}) ORDER BY #{opts[:order]} LIMIT #{opts[:limit]}"
end
def ugly_select_clause(query, opts)
klass = opts[:klass]
select_clause ='DISTINCT %s.id, %s.updated_at AS updated_at, %s.created_at AS created_at' % [klass.table_name, klass.table_name, klass.table_name]
query.select(select_clause).order(opts[:order_with_table]).where(klass.arel_table[opts[:order_field]].lt(opts[:max_time]))
end
def construct_shareable_from_others_query(opts)
conditions = {
:pending => false,
:share_visibilities => {:hidden => opts[:hidden]},
:contacts => {:user_id => self.id, :receiving => true}
}
conditions[:type] = opts[:type] if opts.has_key?(:type)
query = opts[:klass].joins(:contacts).where(conditions)
if opts[:by_members_of]
query = query.joins(:contacts => :aspect_memberships).where(
:aspect_memberships => {:aspect_id => opts[:by_members_of]})
end
ugly_select_clause(query, opts)
end
def construct_public_followings_sql(opts)
logger.debug "[EVIL-QUERY] user.construct_public_followings_sql"
# For PostgreSQL and MySQL/MariaDB we use a different query
# see issue: https://github.com/diaspora/diaspora/issues/5014
if AppConfig.postgres?
query = opts[:klass].where(:author_id => Person.in_aspects(opts[:by_members_of]).select("people.id"), :public => true, :pending => false)
else
aspects = Aspect.where(:id => opts[:by_members_of])
person_ids = Person.connection.select_values(people_in_aspects(aspects).select("people.id").to_sql)
query = opts[:klass].where(:author_id => person_ids, :public => true, :pending => false)
end
unless(opts[:klass] == Photo)
query = query.where(:type => opts[:type])
end
ugly_select_clause(query, opts)
end
def construct_shareable_from_self_query(opts)
conditions = {:pending => false, :author_id => self.person_id }
conditions[:type] = opts[:type] if opts.has_key?(:type)
query = opts[:klass].where(conditions)
if opts[:by_members_of]
query = query.joins(:aspect_visibilities).where(:aspect_visibilities => {:aspect_id => opts[:by_members_of]})
end
ugly_select_clause(query, opts)
visible_ids_from_sql(klass, prep_opts(klass, opts))
end
def contact_for(person)
......@@ -144,18 +66,88 @@ module User::Querying
end
def posts_from(person)
::EvilQuery::ShareablesFromPerson.new(self, Post, person).make_relation!
Post.from_person_visible_by_user(self, person).order("posts.created_at desc")
end
def photos_from(person, opts={})
opts = prep_opts(Photo, opts)
::EvilQuery::ShareablesFromPerson.new(self, Photo, person).make_relation!
Photo.from_person_visible_by_user(self, person)
.by_max_time(opts[:max_time])
.limit(opts[:limit])
end
protected
# @return [Array<Integer>]
def visible_ids_from_sql(klass, opts)
opts[:klass] = klass
opts[:by_members_of] ||= aspect_ids
klass.connection.select_values(visible_shareable_sql(opts)).map(&:to_i)
end
def visible_shareable_sql(opts)
shareable_from_others = construct_shareable_from_others_query(opts)
shareable_from_self = construct_shareable_from_self_query(opts)
"(#{shareable_from_others.to_sql} LIMIT #{opts[:limit]}) " \
"UNION ALL (#{shareable_from_self.to_sql} LIMIT #{opts[:limit]}) " \
"ORDER BY #{opts[:order]} LIMIT #{opts[:limit]}"
end
def construct_shareable_from_others_query(opts)
logger.debug "[EVIL-QUERY] user.construct_shareable_from_others_query"
query = visible_shareables_query(posts_from_aspects_query(opts), opts)
query = query.where(type: opts[:type]) unless opts[:klass] == Photo
ugly_select_clause(query, opts)
end
# For PostgreSQL and MySQL/MariaDB we use a different query
# see issue: https://github.com/diaspora/diaspora/issues/5014
def posts_from_aspects_query(opts)
if AppConfig.postgres?
opts[:klass].where(author_id: Person.in_aspects(opts[:by_members_of]).select("people.id"))
else
person_ids = Person.connection.select_values(Person.in_aspects(opts[:by_members_of]).select("people.id").to_sql)
opts[:klass].where(author_id: person_ids)
end
end
def visible_shareables_query(query, opts)
query.with_visibility.where(pending: false).where(
visible_private_shareables(opts).or(opts[:klass].arel_table[:public].eq(true))
)
end
def visible_private_shareables(opts)
ShareVisibility.arel_table[:user_id].eq(id)
.and(ShareVisibility.arel_table[:shareable_type].eq(opts[:klass].to_s))
.and(ShareVisibility.arel_table[:hidden].eq(opts[:hidden]))
end
def construct_shareable_from_self_query(opts)
conditions = {pending: false, author_id: person_id}
conditions[:type] = opts[:type] if opts.has_key?(:type)
query = opts[:klass].where(conditions)
unless opts[:all_aspects?]
query = query.joins(:aspect_visibilities).where(aspect_visibilities: {aspect_id: opts[:by_members_of]})
end
ugly_select_clause(query, opts)
end
def ugly_select_clause(query, opts)
klass = opts[:klass]
table = klass.table_name
select_clause = "DISTINCT %s.id, %s.updated_at AS updated_at, %s.created_at AS created_at" % [table, table, table]
query.select(select_clause).order(opts[:order_with_table])
.where(klass.arel_table[opts[:order_field]].lt(opts[:max_time]))
end
# @return [Hash]
def prep_opts(klass, opts)
defaults = {
......
class LinkShareVisibilitiesWithUser < ActiveRecord::Migration
def up
cleanup_deleted_share_visibilities
remove_columns :share_visibilities, :created_at, :updated_at
add_column :share_visibilities, :user_id, :integer
ShareVisibility.joins("INNER JOIN contacts ON share_visibilities.contact_id = contacts.id")
.update_all("share_visibilities.user_id = contacts.user_id")
remove_foreign_key :share_visibilities, name: :post_visibilities_contact_id_fk
remove_index :share_visibilities, name: :index_post_visibilities_on_contact_id
remove_index :share_visibilities, name: :shareable_and_contact_id
remove_index :share_visibilities, name: :shareable_and_hidden_and_contact_id
remove_column :share_visibilities, :contact_id
change_column :share_visibilities, :user_id, :integer, null: false
ShareVisibility.joins("LEFT OUTER JOIN users ON users.id = share_visibilities.user_id")
.delete_all("users.id is NULL")
add_index :share_visibilities, :user_id
add_index :share_visibilities, %i(shareable_id shareable_type user_id), name: :shareable_and_user_id
add_index :share_visibilities, %i(shareable_id shareable_type hidden user_id),
name: :shareable_and_hidden_and_user_id
add_foreign_key :share_visibilities, :users, name: :share_visibilities_user_id_fk, on_delete: :cascade
end
def down
add_column :share_visibilities, :contact_id, :integer
ShareVisibility.joins("INNER JOIN contacts ON share_visibilities.user_id = contacts.user_id")
.update_all("share_visibilities.contact_id = contacts.id")
remove_foreign_key :share_visibilities, name: :share_visibilities_user_id_fk
remove_index :share_visibilities, :user_id
remove_index :share_visibilities, name: :shareable_and_user_id
remove_index :share_visibilities, name: :shareable_and_hidden_and_user_id
remove_column :share_visibilities, :user_id
change_column :share_visibilities, :contact_id, :integer, null: false
add_index :share_visibilities, :contact_id, name: :index_post_visibilities_on_contact_id
add_index :share_visibilities, %i(shareable_id shareable_type contact_id), name: :shareable_and_contact_id
add_index :share_visibilities, %i(shareable_id shareable_type hidden contact_id),
name: :shareable_and_hidden_and_contact_id
add_foreign_key :share_visibilities, :contacts, name: :post_visibilities_contact_id_fk, on_delete: :cascade
add_column :share_visibilities, :created_at, :datetime
add_column :share_visibilities, :updated_at, :datetime
end
private
def cleanup_deleted_share_visibilities
ShareVisibility.joins("LEFT OUTER JOIN posts ON posts.id = share_visibilities.shareable_id")
.where(shareable_type: "Post").delete_all("posts.id is NULL")
ShareVisibility.joins("LEFT OUTER JOIN photos ON photos.id = share_visibilities.shareable_id")
.where(shareable_type: "Photo").delete_all("photos.id is NULL")
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20151210213023) do
ActiveRecord::Schema.define(version: 20160225232049) do
create_table "account_deletions", force: :cascade do |t|
t.string "diaspora_handle", limit: 255
......@@ -103,15 +103,15 @@ ActiveRecord::Schema.define(version: 20151210213023) do
end
create_table "comments", force: :cascade do |t|
t.text "text", limit: 65535, null: false
t.integer "commentable_id", limit: 4, null: false
t.integer "author_id", limit: 4, null: false
t.string "guid", limit: 255, null: false
t.text "author_signature", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "likes_count", limit: 4, default: 0, null: false
t.string "commentable_type", limit: 60, default: "Post", null: false
t.text "text", limit: 65535, null: false
t.integer "commentable_id", limit: 4, null: false
t.integer "author_id", limit: 4, null: false
t.string "guid", limit: 255, null: false
t.text "author_signature", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "likes_count", limit: 4, default: 0, null: false
t.string "commentable_type", limit: 60, default: "Post", null: false
end
add_index "comments", ["author_id"], name: "index_comments_on_person_id", using: :btree
......@@ -188,14 +188,14 @@ ActiveRecord::Schema.define(version: 20151210213023) do
add_index "invitations", ["sender_id"], name: "index_invitations_on_sender_id", using: :btree
create_table "likes", force: :cascade do |t|
t.boolean "positive", default: true
t.integer "target_id", limit: 4
t.integer "author_id", limit: 4
t.string "guid", limit: 255
t.text "author_signature", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "target_type", limit: 60, null: false
t.boolean "positive", default: true
t.integer "target_id", limit: 4
t.integer "author_id", limit: 4
t.string "guid", limit: 255
t.text "author_signature", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "target_type", limit: 60, null: false
end
add_index "likes", ["author_id"], name: "likes_author_id_fk", using: :btree
......@@ -222,13 +222,13 @@ ActiveRecord::Schema.define(version: 20151210213023) do
add_index "mentions", ["post_id"], name: "index_mentions_on_post_id", using: :btree
create_table "messages", force: :cascade do |t|
t.integer "conversation_id", limit: 4, null: false
t.integer "author_id", limit: 4, null: false
t.string "guid", limit: 255, null: false
t.text "text", limit: 65535, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "author_signature", limit: 65535
t.integer "conversation_id", limit: 4, null: false
t.integer "author_id", limit: 4, null: false
t.string "guid", limit: 255, null: false
t.text "text", limit: 65535, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "author_signature", limit: 65535
end
add_index "messages", ["author_id"], name: "index_messages_on_author_id", using: :btree
......@@ -312,14 +312,14 @@ ActiveRecord::Schema.define(version: 20151210213023) do
end
create_table "participations", force: :cascade do |t|
t.string "guid", limit: 255
t.integer "target_id", limit: 4
t.string "target_type", limit: 60, null: false
t.integer "author_id", limit: 4
t.text "author_signature", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "count", limit: 4, default: 1, null: false
t.string "guid", limit: 255
t.integer "target_id", limit: 4
t.string "target_type", limit: 60, null: false
t.integer "author_id", limit: 4
t.text "author_signature", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "count", limit: 4, default: 1, null: false
end
add_index "participations", ["guid"], name: "index_participations_on_guid", length: {"guid"=>191}, using: :btree
......@@ -392,11 +392,11 @@ ActiveRecord::Schema.define(version: 20151210213023) do
add_index "poll_answers", ["poll_id"], name: "index_poll_answers_on_poll_id", using: :btree
create_table "poll_participations", force: :cascade do |t|
t.integer "poll_answer_id", limit: 4, null: false
t.integer "author_id", limit: 4, null: false
t.integer "poll_id", limit: 4, null: false
t.string "guid", limit: 255
t.text "author_signature", limit: 65535
t.integer "poll_answer_id", limit: 4, null: false
t.integer "author_id", limit: 4, null: false
t.integer "poll_id", limit: 4, null: false
t.string "guid", limit: 255
t.text "author_signature", limit: 65535
t.datetime "created_at"
t.datetime "updated_at"
end
......@@ -542,18 +542,16 @@ ActiveRecord::Schema.define(version: 20151210213023) do
add_index "services", ["user_id"], name: "index_services_on_user_id", using: :btree
create_table "share_visibilities", force: :cascade do |t|
t.integer "shareable_id", limit: 4, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "hidden", default: false, null: false
t.integer "contact_id", limit: 4, null: false
t.string "shareable_type", limit: 60, default: "Post", null: false
t.integer "shareable_id", limit: 4, null: false
t.boolean "hidden", default: false, null: false
t.string "shareable_type", limit: 60, default: "Post", null: false
t.integer "user_id", limit: 4, null: false
end
add_index "share_visibilities", ["contact_id"], name: "index_post_visibilities_on_contact_id", using: :btree
add_index "share_visibilities", ["shareable_id", "shareable_type", "contact_id"], name: "shareable_and_contact_id", using: :btree
add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "contact_id"], name: "shareable_and_hidden_and_contact_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"], name: "index_post_visibilities_on_post_id", using: :btree
add_index "share_visibilities", ["user_id"], name: "index_share_visibilities_on_user_id", using: :btree
create_table "simple_captcha_data", force: :cascade do |t|
t.string "key", limit: 40
......@@ -679,5 +677,5 @@ ActiveRecord::Schema.define(version: 20151210213023) do
add_foreign_key "ppid", "users"
add_foreign_key "profiles", "people", name: "profiles_person_id_fk", on_delete: :cascade
add_foreign_key "services", "users", name: "services_user_id_fk", on_delete: :cascade
add_foreign_key "share_visibilities", "contacts", name: "post_visibilities_contact_id_fk", on_delete: :cascade
add_foreign_key "share_visibilities", "users", name: "share_visibilities_user_id_fk", on_delete: :cascade
end
......@@ -27,7 +27,6 @@ class AccountDeleter
#person
delete_standard_person_associations
remove_conversation_visibilities
remove_share_visibilities_on_persons_posts
delete_contacts_of_me
tombstone_person_and_profile
......@@ -56,7 +55,7 @@ class AccountDeleter
def ignored_ar_user_associations
%i(followed_tags invited_by contact_people aspect_memberships
ignored_people conversation_visibilities conversations reports)
ignored_people share_visibilities conversation_visibilities conversations reports)
end
def delete_standard_user_associations
......@@ -83,12 +82,8 @@ class AccountDeleter
# Currently this would get deleted due to the db foreign key constrainsts,
# but we'll keep this method here for completeness
def remove_share_visibilities_on_persons_posts
ShareVisibility.for_contacts_of_a_person(person).destroy_all
end
def remove_share_visibilities_on_contacts_posts
ShareVisibility.for_a_users_contacts(user).destroy_all
ShareVisibility.for_a_user(user).destroy_all
end
def remove_conversation_visibilities
......
......@@ -33,14 +33,14 @@ module Diaspora
end
# @param [User] user The user that is receiving this shareable.
# @param [Person] person The person who dispatched this shareable to the
# @param [Person] _person The sender of the shareable
# @return [void]
def receive(user, person)
def receive(user, _person)
local_shareable = persisted_shareable
if local_shareable
receive_persisted(user, person, local_shareable) if verify_persisted_shareable(local_shareable)
receive_persisted(user, local_shareable) if verify_persisted_shareable(local_shareable)
else
receive_non_persisted(user, person)
receive_non_persisted(user)
end
end
......@@ -81,12 +81,12 @@ module Diaspora
false
end
def receive_persisted(user, person, shareable)
def receive_persisted(user, shareable)
known_shareable = user.find_visible_shareable_by_id(self.class.base_class, guid, key: :guid)
if known_shareable
update_existing_sharable(known_shareable)
else
receive_shareable_visibility(user, person, shareable)
receive_shareable_visibility(user, shareable)
end
end
......@@ -101,18 +101,18 @@ module Diaspora
end
end
def receive_shareable_visibility(user, person, shareable)
user.contact_for(person).receive_shareable(shareable)
def receive_shareable_visibility(user, shareable)
user.receive_shareable(shareable)
user.notify_if_mentioned(shareable)
logger.info "event=receive payload_type=#{self.class} status=complete " \
"sender=#{diaspora_handle} receiver=#{person.diaspora_handle} guid=#{shareable.guid}"
"sender=#{diaspora_handle} receiver=#{user.diaspora_handle} guid=#{shareable.guid}"
end
def receive_non_persisted(user, person)
def receive_non_persisted(user)
if save
logger.info "event=receive payload_type=#{self.class} status=complete sender=#{diaspora_handle} " \
"guid=#{guid}"
receive_shareable_visibility(user, person, self)
receive_shareable_visibility(user, self)
else
logger.warn "event=receive payload_type=#{self.class} status=abort sender=#{diaspora_handle} " \
"reason=#{errors.full_messages} guid=#{guid}"
......@@ -122,7 +122,7 @@ module Diaspora
logger.info "event=receive payload_type=#{self.class} status=retry sender=#{diaspora_handle} guid=#{guid}"
local_shareable = persisted_shareable
raise e unless local_shareable
receive_shareable_visibility(user, person, local_shareable) if verify_persisted_shareable(local_shareable)
receive_shareable_visibility(user, local_shareable) if verify_persisted_shareable(local_shareable)
end
end
end
......
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
#the pont of this object is to centralize the simmilarities of Photo and post,
# the point of this object is to centralize the simmilarities of Photo and Post,
# as they used to be the same class
module Diaspora
module Shareable
def self.included(model)
model.instance_eval do
has_many :aspect_visibilities, as: :shareable, validate: false
has_many :aspects, through: :aspect_visibilities
has_many :aspect_visibilities, :as => :shareable, :validate => false
has_many :aspects, :through => :aspect_visibilities
has_many :share_visibilities, :as => :shareable
has_many :contacts, :through => :share_visibilities
has_many :share_visibilities, as: :shareable, dependent: :delete_all
belongs_to :author, :class_name => 'Person'
belongs_to :author, class_name: "Person"
delegate :id, :name, :first_name, to: :author, prefix: true
#scopes
scope :all_public, -> { where(:public => true, :pending => false) }
# scopes
scope :all_public, -> { where(public: true, pending: false) }
scope :with_visibility, -> {
joins("LEFT OUTER JOIN share_visibilities ON share_visibilities.shareable_id = #{table_name}.id")
}
def self.owned_or_visible_by_user(user)
self.joins("LEFT OUTER JOIN share_visibilities ON share_visibilities.shareable_id = posts.id AND share_visibilities.shareable_type = 'Post'").
joins("LEFT OUTER JOIN contacts ON contacts.id = share_visibilities.contact_id").
where(
Contact.arel_table[:user_id].eq(user.id).or(
self.arel_table[:public].eq(true).or(
self.arel_table[:author_id].eq(user.person_id)
)
)
).
select("DISTINCT #{self.table_name}.*")
with_visibility.where(
visible_by_user(user).or(arel_table[:public].eq(true)
.or(arel_table[:author_id].eq(user.person_id)))
).select("DISTINCT #{table_name}.*")
end
def self.from_person_visible_by_user(user, person)
return owned_by_user(user) if person == user.person
with_visibility.where(author_id: person.id).where(
visible_by_user(user).or(arel_table[:public].eq(true))
).select("DISTINCT #{table_name}.*")
end
def self.for_visible_shareable_sql(max_time, order, limit=15, types=Stream::Base::TYPES_OF_POST_IN_STREAM)
by_max_time(max_time, order).order(table_name + ".id DESC").where(type: types).limit(limit)
end
def self.by_max_time(max_time, order="created_at")
where("#{table_name}.#{order} < ?", max_time).order("#{table_name}.#{order} DESC")
end
def self.for_visible_shareable_sql(max_time, order, limit = 15, types = Stream::Base::TYPES_OF_POST_IN_STREAM)
by_max_time(max_time, order).
where(:type => types).
limit(limit)
def self.owned_by_user(user)
user.person.send(table_name).where(pending: false)
end
def self.by_max_time(max_time, order='created_at')
where("#{self.table_name}.#{order} < ?", max_time).order