mirror of https://github.com/mastodon/mastodon
Rename :poll to :preloadable_poll and :owned_poll to :poll on Status (#10401)
Also, fix some n+1 queries Resolve #10365
This commit is contained in:
parent
f46f67d984
commit
f1bc90ab50
|
@ -105,8 +105,8 @@ module StreamEntriesHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_summary(status)
|
def poll_summary(status)
|
||||||
return unless status.poll
|
return unless status.preloadable_poll
|
||||||
status.poll.options.map { |o| "[ ] #{o}" }.join("\n")
|
status.preloadable_poll.options.map { |o| "[ ] #{o}" }.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
def status_description(status)
|
def status_description(status)
|
||||||
|
|
|
@ -68,7 +68,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
thread: replied_to_status,
|
thread: replied_to_status,
|
||||||
conversation: conversation_from_uri(@object['conversation']),
|
conversation: conversation_from_uri(@object['conversation']),
|
||||||
media_attachment_ids: process_attachments.take(4).map(&:id),
|
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||||
owned_poll: process_poll,
|
poll: process_poll,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -240,11 +240,11 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_vote?
|
def poll_vote?
|
||||||
return false if replied_to_status.nil? || replied_to_status.poll.nil? || !replied_to_status.local? || !replied_to_status.poll.options.include?(@object['name'])
|
return false if replied_to_status.nil? || replied_to_status.preloadable_poll.nil? || !replied_to_status.local? || !replied_to_status.preloadable_poll.options.include?(@object['name'])
|
||||||
|
|
||||||
unless replied_to_status.poll.expired?
|
unless replied_to_status.preloadable_poll.expired?
|
||||||
replied_to_status.poll.votes.create!(account: @account, choice: replied_to_status.poll.options.index(@object['name']), uri: @object['id'])
|
replied_to_status.preloadable_poll.votes.create!(account: @account, choice: replied_to_status.preloadable_poll.options.index(@object['name']), uri: @object['id'])
|
||||||
ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, replied_to_status.id) unless replied_to_status.poll.hide_totals?
|
ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, replied_to_status.id) unless replied_to_status.preloadable_poll.hide_totals?
|
||||||
end
|
end
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
|
@ -23,8 +23,8 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
|
||||||
return reject_payload! if invalid_origin?(@object['id'])
|
return reject_payload! if invalid_origin?(@object['id'])
|
||||||
|
|
||||||
status = Status.find_by(uri: object_uri, account_id: @account.id)
|
status = Status.find_by(uri: object_uri, account_id: @account.id)
|
||||||
return if status.nil? || status.poll.nil?
|
return if status.nil? || status.preloadable_poll.nil?
|
||||||
|
|
||||||
ActivityPub::ProcessPollService.new.call(status.poll, @object)
|
ActivityPub::ProcessPollService.new.call(status.preloadable_poll, @object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,8 +19,8 @@ class Formatter
|
||||||
|
|
||||||
raw_content = status.text
|
raw_content = status.text
|
||||||
|
|
||||||
if options[:inline_poll_options] && status.poll
|
if options[:inline_poll_options] && status.preloadable_poll
|
||||||
raw_content = raw_content + "\n\n" + status.poll.options.map { |title| "[ ] #{title}" }.join("\n")
|
raw_content = raw_content + "\n\n" + status.preloadable_poll.options.map { |title| "[ ] #{title}" }.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
return '' if raw_content.blank?
|
return '' if raw_content.blank?
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Notification < ApplicationRecord
|
||||||
poll: 'Poll',
|
poll: 'Poll',
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
STATUS_INCLUDES = [:account, :application, :media_attachments, :tags, active_mentions: :account, reblog: [:account, :application, :media_attachments, :tags, active_mentions: :account]].freeze
|
STATUS_INCLUDES = [:account, :application, :preloadable_poll, :media_attachments, :tags, active_mentions: :account, reblog: [:account, :application, :preloadable_poll, :media_attachments, :tags, active_mentions: :account]].freeze
|
||||||
|
|
||||||
belongs_to :account, optional: true
|
belongs_to :account, optional: true
|
||||||
belongs_to :from_account, class_name: 'Account', optional: true
|
belongs_to :from_account, class_name: 'Account', optional: true
|
||||||
|
|
|
@ -45,7 +45,7 @@ class Status < ApplicationRecord
|
||||||
belongs_to :account, inverse_of: :statuses
|
belongs_to :account, inverse_of: :statuses
|
||||||
belongs_to :in_reply_to_account, foreign_key: 'in_reply_to_account_id', class_name: 'Account', optional: true
|
belongs_to :in_reply_to_account, foreign_key: 'in_reply_to_account_id', class_name: 'Account', optional: true
|
||||||
belongs_to :conversation, optional: true
|
belongs_to :conversation, optional: true
|
||||||
belongs_to :poll, optional: true
|
belongs_to :preloadable_poll, class_name: 'Poll', foreign_key: 'poll_id', optional: true
|
||||||
|
|
||||||
belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies, optional: true
|
belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies, optional: true
|
||||||
belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true
|
belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true
|
||||||
|
@ -63,7 +63,7 @@ class Status < ApplicationRecord
|
||||||
has_one :notification, as: :activity, dependent: :destroy
|
has_one :notification, as: :activity, dependent: :destroy
|
||||||
has_one :stream_entry, as: :activity, inverse_of: :status
|
has_one :stream_entry, as: :activity, inverse_of: :status
|
||||||
has_one :status_stat, inverse_of: :status
|
has_one :status_stat, inverse_of: :status
|
||||||
has_one :owned_poll, class_name: 'Poll', inverse_of: :status, dependent: :destroy
|
has_one :poll, inverse_of: :status, dependent: :destroy
|
||||||
|
|
||||||
validates :uri, uniqueness: true, presence: true, unless: :local?
|
validates :uri, uniqueness: true, presence: true, unless: :local?
|
||||||
validates :text, presence: true, unless: -> { with_media? || reblog? }
|
validates :text, presence: true, unless: -> { with_media? || reblog? }
|
||||||
|
@ -72,7 +72,7 @@ class Status < ApplicationRecord
|
||||||
validates :reblog, uniqueness: { scope: :account }, if: :reblog?
|
validates :reblog, uniqueness: { scope: :account }, if: :reblog?
|
||||||
validates :visibility, exclusion: { in: %w(direct limited) }, if: :reblog?
|
validates :visibility, exclusion: { in: %w(direct limited) }, if: :reblog?
|
||||||
|
|
||||||
accepts_nested_attributes_for :owned_poll
|
accepts_nested_attributes_for :poll
|
||||||
|
|
||||||
default_scope { recent }
|
default_scope { recent }
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ class Status < ApplicationRecord
|
||||||
:tags,
|
:tags,
|
||||||
:preview_cards,
|
:preview_cards,
|
||||||
:stream_entry,
|
:stream_entry,
|
||||||
:poll,
|
:preloadable_poll,
|
||||||
account: :account_stat,
|
account: :account_stat,
|
||||||
active_mentions: { account: :account_stat },
|
active_mentions: { account: :account_stat },
|
||||||
reblog: [
|
reblog: [
|
||||||
|
@ -118,7 +118,7 @@ class Status < ApplicationRecord
|
||||||
:media_attachments,
|
:media_attachments,
|
||||||
:conversation,
|
:conversation,
|
||||||
:status_stat,
|
:status_stat,
|
||||||
:poll,
|
:preloadable_poll,
|
||||||
account: :account_stat,
|
account: :account_stat,
|
||||||
active_mentions: { account: :account_stat },
|
active_mentions: { account: :account_stat },
|
||||||
],
|
],
|
||||||
|
@ -214,10 +214,11 @@ class Status < ApplicationRecord
|
||||||
|
|
||||||
def emojis
|
def emojis
|
||||||
return @emojis if defined?(@emojis)
|
return @emojis if defined?(@emojis)
|
||||||
|
|
||||||
fields = [spoiler_text, text]
|
fields = [spoiler_text, text]
|
||||||
fields += owned_poll.options unless owned_poll.nil?
|
fields += preloadable_poll.options unless preloadable_poll.nil?
|
||||||
|
|
||||||
@emojis = CustomEmoji.from_text(fields.join(' '), account.domain)
|
@emojis = CustomEmoji.from_text(fields.join(' '), account.domain)
|
||||||
@emojis
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def mark_for_mass_destruction!
|
def mark_for_mass_destruction!
|
||||||
|
@ -453,7 +454,7 @@ class Status < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_poll_id
|
def set_poll_id
|
||||||
update_column(:poll_id, owned_poll.id) unless owned_poll.nil?
|
update_column(:poll_id, poll.id) unless poll.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_visibility
|
def set_visibility
|
||||||
|
|
|
@ -29,7 +29,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def type
|
def type
|
||||||
object.poll ? 'Question' : 'Note'
|
object.preloadable_poll ? 'Question' : 'Note'
|
||||||
end
|
end
|
||||||
|
|
||||||
def summary
|
def summary
|
||||||
|
@ -125,29 +125,29 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_options
|
def poll_options
|
||||||
object.poll.loaded_options
|
object.preloadable_poll.loaded_options
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_and_multiple?
|
def poll_and_multiple?
|
||||||
object.poll&.multiple?
|
object.preloadable_poll&.multiple?
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_and_not_multiple?
|
def poll_and_not_multiple?
|
||||||
object.poll && !object.poll.multiple?
|
object.preloadable_poll && !object.preloadable_poll.multiple?
|
||||||
end
|
end
|
||||||
|
|
||||||
def closed
|
def closed
|
||||||
object.poll.expires_at.iso8601
|
object.preloadable_poll.expires_at.iso8601
|
||||||
end
|
end
|
||||||
|
|
||||||
alias end_time closed
|
alias end_time closed
|
||||||
|
|
||||||
def poll_and_expires?
|
def poll_and_expires?
|
||||||
object.poll&.expires_at&.present?
|
object.preloadable_poll&.expires_at&.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_and_expired?
|
def poll_and_expired?
|
||||||
object.poll&.expired?
|
object.preloadable_poll&.expired?
|
||||||
end
|
end
|
||||||
|
|
||||||
class MediaAttachmentSerializer < ActivityPub::Serializer
|
class MediaAttachmentSerializer < ActivityPub::Serializer
|
||||||
|
|
|
@ -6,7 +6,7 @@ class ActivityPub::UpdatePollSerializer < ActivityPub::Serializer
|
||||||
has_one :object, serializer: ActivityPub::NoteSerializer
|
has_one :object, serializer: ActivityPub::NoteSerializer
|
||||||
|
|
||||||
def id
|
def id
|
||||||
[ActivityPub::TagManager.instance.uri_for(object), '#updates/', object.poll.updated_at.to_i].join
|
[ActivityPub::TagManager.instance.uri_for(object), '#updates/', object.preloadable_poll.updated_at.to_i].join
|
||||||
end
|
end
|
||||||
|
|
||||||
def type
|
def type
|
||||||
|
|
|
@ -21,7 +21,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
has_many :emojis, serializer: REST::CustomEmojiSerializer
|
has_many :emojis, serializer: REST::CustomEmojiSerializer
|
||||||
|
|
||||||
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
||||||
has_one :poll, serializer: REST::PollSerializer
|
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
||||||
|
|
||||||
def id
|
def id
|
||||||
object.id.to_s
|
object.id.to_s
|
||||||
|
|
|
@ -155,7 +155,7 @@ class PostStatusService < BaseService
|
||||||
text: @text,
|
text: @text,
|
||||||
media_attachments: @media || [],
|
media_attachments: @media || [],
|
||||||
thread: @in_reply_to,
|
thread: @in_reply_to,
|
||||||
owned_poll_attributes: poll_attributes,
|
poll_attributes: poll_attributes,
|
||||||
sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?,
|
sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?,
|
||||||
spoiler_text: @options[:spoiler_text] || '',
|
spoiler_text: @options[:spoiler_text] || '',
|
||||||
visibility: @visibility,
|
visibility: @visibility,
|
||||||
|
|
|
@ -22,9 +22,9 @@
|
||||||
%a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
|
%a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
|
||||||
.e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
|
.e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
|
||||||
|
|
||||||
- if status.poll
|
- if status.preloadable_poll
|
||||||
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
||||||
= render partial: 'stream_entries/poll', locals: { status: status, poll: status.poll, autoplay: autoplay }
|
= render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
|
||||||
- elsif !status.media_attachments.empty?
|
- elsif !status.media_attachments.empty?
|
||||||
- if status.media_attachments.first.video?
|
- if status.media_attachments.first.video?
|
||||||
- video = status.media_attachments.first
|
- video = status.media_attachments.first
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
%a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
|
%a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
|
||||||
.e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
|
.e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
|
||||||
|
|
||||||
- if status.poll
|
- if status.preloadable_poll
|
||||||
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
||||||
= render partial: 'stream_entries/poll', locals: { status: status, poll: status.poll, autoplay: autoplay }
|
= render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
|
||||||
- elsif !status.media_attachments.empty?
|
- elsif !status.media_attachments.empty?
|
||||||
- if status.media_attachments.first.video?
|
- if status.media_attachments.first.video?
|
||||||
- video = status.media_attachments.first
|
- video = status.media_attachments.first
|
||||||
|
|
|
@ -9,7 +9,7 @@ class ActivityPub::DistributePollUpdateWorker
|
||||||
@status = Status.find(status_id)
|
@status = Status.find(status_id)
|
||||||
@account = @status.account
|
@account = @status.account
|
||||||
|
|
||||||
return unless @status.poll
|
return unless @status.preloadable_poll
|
||||||
|
|
||||||
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
||||||
[payload, @account.id, inbox_url]
|
[payload, @account.id, inbox_url]
|
||||||
|
@ -29,7 +29,7 @@ class ActivityPub::DistributePollUpdateWorker
|
||||||
def inboxes
|
def inboxes
|
||||||
return @inboxes if defined?(@inboxes)
|
return @inboxes if defined?(@inboxes)
|
||||||
|
|
||||||
@inboxes = [@status.mentions, @status.reblogs, @status.poll.votes].flat_map do |relation|
|
@inboxes = [@status.mentions, @status.reblogs, @status.preloadable_poll.votes].flat_map do |relation|
|
||||||
relation.includes(:account).map do |record|
|
relation.includes(:account).map do |record|
|
||||||
record.account.preferred_inbox_url if !record.account.local? && record.account.activitypub?
|
record.account.preferred_inbox_url if !record.account.local? && record.account.activitypub?
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
en:
|
en:
|
||||||
activerecord:
|
activerecord:
|
||||||
attributes:
|
attributes:
|
||||||
status:
|
poll:
|
||||||
owned_poll: Poll
|
expires_at: Deadline
|
||||||
|
options: Choices
|
||||||
errors:
|
errors:
|
||||||
models:
|
models:
|
||||||
account:
|
account:
|
||||||
|
|
|
@ -464,7 +464,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
|
|
||||||
context 'when a vote to a local poll' do
|
context 'when a vote to a local poll' do
|
||||||
let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) }
|
let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) }
|
||||||
let!(:local_status) { Fabricate(:status, owned_poll: poll) }
|
let!(:local_status) { Fabricate(:status, poll: poll) }
|
||||||
|
|
||||||
let(:object_json) do
|
let(:object_json) do
|
||||||
{
|
{
|
||||||
|
@ -489,7 +489,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
poll.save(validate: false)
|
poll.save(validate: false)
|
||||||
poll
|
poll
|
||||||
end
|
end
|
||||||
let!(:local_status) { Fabricate(:status, owned_poll: poll) }
|
let!(:local_status) { Fabricate(:status, poll: poll) }
|
||||||
|
|
||||||
let(:object_json) do
|
let(:object_json) do
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue