mirror of
https://github.com/indentlabs/notebook.git
synced 2025-10-26 11:19:22 +00:00
163 lines
6.6 KiB
Ruby
163 lines
6.6 KiB
Ruby
require 'active_support/concern'
|
|
|
|
module HasContent
|
|
extend ActiveSupport::Concern
|
|
|
|
included do
|
|
Rails.application.config.content_types[:all].each do |content_type|
|
|
content_type_sym = content_type.name.downcase.pluralize.to_sym # :characters
|
|
|
|
#has_many :characters, :locations, etc
|
|
has_many content_type_sym, dependent: :destroy
|
|
end
|
|
has_many :timelines
|
|
|
|
has_many :attribute_fields
|
|
has_many :attribute_categories
|
|
has_many :attribute_values, class_name: 'Attribute', dependent: :destroy
|
|
|
|
# {
|
|
# characters: [...],
|
|
# locations: [...]
|
|
# }
|
|
def content(
|
|
content_types: Rails.application.config.content_types[:all].map(&:name),
|
|
page_scoping: { user_id: self.id },
|
|
universe_id: nil
|
|
)
|
|
return {} if content_types.empty?
|
|
|
|
polymorphic_content_fields = [:id, :name, :page_type, :user_id, :created_at, :updated_at, :deleted_at, :archived_at, :privacy]
|
|
where_conditions = page_scoping.map { |key, value| "#{key} = #{value}" }.join(' AND ') + ' AND deleted_at IS NULL AND archived_at IS NULL'
|
|
|
|
sql = content_types.uniq.map do |page_type|
|
|
if page_type != 'Universe'
|
|
# Even though we're selecting universe_id here, it's still absent from all of the result rows. No idea why.
|
|
# Removing Universe from `content_types` and adding universe_id to the content_fields works, so maybe it's something to
|
|
# do with UNIONing the NULL column?
|
|
# clause = "SELECT #{polymorphic_content_fields.join(',')},universe_id FROM #{page_type.downcase.pluralize} WHERE #{where_conditions}"
|
|
clause = "SELECT #{polymorphic_content_fields.join(',')} FROM #{page_type.downcase.pluralize} WHERE #{where_conditions}"
|
|
else
|
|
# clause = "SELECT #{polymorphic_content_fields.join(',')},id FROM #{page_type.downcase.pluralize} WHERE #{where_conditions}"
|
|
clause = "SELECT #{polymorphic_content_fields.join(',')} FROM #{page_type.downcase.pluralize} WHERE #{where_conditions}"
|
|
end
|
|
|
|
if universe_id.present? && page_type != 'Universe'
|
|
clause += " AND universe_id = #{universe_id}"
|
|
end
|
|
clause
|
|
end.compact.join(' UNION ALL ') + ' ORDER BY page_type, id'
|
|
|
|
result = ActiveRecord::Base.connection.execute(sql)
|
|
@content_by_page_type ||= result.to_a.each_with_object({}) do |object, hash|
|
|
object.keys.each do |key|
|
|
object.except!(key) if key.is_a?(Integer)
|
|
end
|
|
|
|
hash[object['page_type']] ||= []
|
|
hash[object['page_type']] << ContentPage.new(object)
|
|
end
|
|
end
|
|
|
|
# [..., ...]
|
|
def content_list(
|
|
content_types: Rails.application.config.content_types[:all].map(&:name),
|
|
page_scoping: { user_id: self.id }
|
|
)
|
|
|
|
# todo we can't select for universe_id here which kind of sucks, so we need to research 1) the repercussions, 2) what to do instead
|
|
polymorphic_content_fields = [:id, :name, :page_type, :user_id, :created_at, :updated_at, :deleted_at, :archived_at, :privacy]
|
|
where_conditions = page_scoping.map { |key, value| "#{key} = #{value}" }.join(' AND ') + ' AND deleted_at IS NULL AND archived_at IS NULL'
|
|
|
|
sql = content_types.uniq.map do |page_type|
|
|
"SELECT #{polymorphic_content_fields.join(',')} FROM #{page_type.downcase.pluralize} WHERE #{where_conditions}"
|
|
end.join(' UNION ALL ')
|
|
|
|
@user_content_list ||= ActiveRecord::Base.connection.execute(sql)
|
|
end
|
|
|
|
# {
|
|
# characters: [...],
|
|
# locations: [...]
|
|
# }
|
|
def content_in_universe universe_id
|
|
@user_content_in_universe ||= content_list(page_scoping: { user_id: self.id, universe_id: universe_id }).group_by(&:page_type)
|
|
end
|
|
|
|
# 5
|
|
def content_count
|
|
@user_content_count ||= content_list.count
|
|
end
|
|
|
|
# {
|
|
# characters: [...],
|
|
# locations: [...],
|
|
# }
|
|
def public_content
|
|
@user_public_content ||= begin
|
|
content_value = {}
|
|
|
|
Rails.application.config.content_types[:all].each do |type|
|
|
relation = type.name.downcase.pluralize.to_sym # :characters
|
|
content_value[relation] = send(relation).is_public
|
|
end
|
|
|
|
content_value
|
|
end
|
|
end
|
|
|
|
# 8
|
|
def public_content_count
|
|
@user_content_count ||= begin
|
|
Rails.application.config.content_types[:all].map do |type|
|
|
relation = type.name.downcase.pluralize.to_sym # :characters
|
|
send(relation).is_public.count
|
|
end.sum
|
|
end
|
|
end
|
|
|
|
# [..., ..., ...]
|
|
def recent_content_list(limit: 10)
|
|
# Todo: I think this is more optimized, but the group introduces weird
|
|
# ordering of the results, so we're building it a bit less optimized below
|
|
# just to ensure it's actually correct.
|
|
# recently_changed_attributes = Attribute.where(user: self)
|
|
# .order('updated_at desc')
|
|
# .group([:entity_type, :entity_id])
|
|
# .limit(10)
|
|
|
|
recently_changed_attributes = Attribute.where(user: self)
|
|
.order('updated_at desc')
|
|
.limit(limit * 100)
|
|
.group_by { |r| [r.entity_type, r.entity_id] }
|
|
.keys
|
|
.first(limit)
|
|
|
|
@user_recent_content_list = recently_changed_attributes.map do |entity_type, entity_id|
|
|
entity_type.constantize.find_by(id: entity_id) rescue nil
|
|
end.compact
|
|
end
|
|
|
|
def recent_content_list_by_create(limit: 10)
|
|
# Todo: I think this is more optimized, but the group introduces weird
|
|
# ordering of the results, so we're building it a bit less optimized below
|
|
# just to ensure it's actually correct.
|
|
# recently_changed_attributes = Attribute.where(user: self)
|
|
# .order('updated_at desc')
|
|
# .group([:entity_type, :entity_id])
|
|
# .limit(10)
|
|
|
|
recently_changed_attributes = Attribute.where(user: self)
|
|
.order('created_at desc')
|
|
.limit(limit * 100)
|
|
.group_by { |r| [r.entity_type, r.entity_id] }
|
|
.keys
|
|
.first(limit)
|
|
|
|
@user_recent_content_list = recently_changed_attributes.map do |entity_type, entity_id|
|
|
entity_type.constantize.find_by(id: entity_id)
|
|
end.compact
|
|
end
|
|
end
|
|
end
|