1
0
Fork 0
forked from OpenNeo/impress
impress/app/models/contribution.rb
Matchu f997513e87 Update to new scope syntax
Ohh ok, without this change all of our `scope`s were just immediately evaluating the argument and fetching _all_ such matching records immediately, instead of waiting to actually be called. This led to bugs like `pet_type.as_json` returning ALL pet states in the whole db, because the `PetState.emotion_order` scope was being treated as a single predefined query, rather than a query fragment to merge into the current context.

This also explains what happened in 724ed83: that's why things before the scope in the query were being ignored.
2023-07-22 14:04:01 -07:00

82 lines
2.8 KiB
Ruby

class Contribution < ActiveRecord::Base
POINT_VALUES = {
'Item' => 3,
'SwfAsset' => 2,
'PetType' => 15,
'PetState' => 10
}
belongs_to :contributed, :polymorphic => true
belongs_to :user
scope :recent, -> { order('id DESC') }
cattr_reader :per_page
@@per_page = 30
def point_value
POINT_VALUES[contributed_type] ||
raise("unexpected contributed type #{contributed_type.inspect} for " +
"contributed #{contributed.inspect}")
end
CONTRIBUTED_RELATIONSHIPS = {
'SwfAsset' => 'Item',
'PetState' => 'PetType'
}
CONTRIBUTED_CHILDREN = CONTRIBUTED_RELATIONSHIPS.keys
CONTRIBUTED_TYPES = CONTRIBUTED_CHILDREN + CONTRIBUTED_RELATIONSHIPS.values
def self.preload_contributeds_and_parents(contributions, options={})
options[:scopes] ||= {}
# Initialize the groups we'll be using for quick access
contributions_by_type = {}
contributed_by_type = {}
contributed_by_type_and_id = {}
needed_ids_by_type = {}
CONTRIBUTED_TYPES.each do |type|
contributions_by_type[type] = []
contributed_by_type[type] = []
contributed_by_type_and_id[type] = {}
needed_ids_by_type[type] = []
end
# Go through the contributions to sort them for future contributed
# assignment, and so we can know what immediate contributed items we'll
# need to look up
contributions.each do |contribution|
type = contribution.contributed_type
contributions_by_type[type] << contribution
needed_ids_by_type[type] << contribution.contributed_id
end
# Load contributed objects without parents, prepare them for easy access
# for future assignment to contributions and looking up parents
CONTRIBUTED_CHILDREN.each do |type|
scope = options[:scopes][type] || type.constantize.scoped
scope.find(needed_ids_by_type[type]).each do |contributed|
contributed_by_type[type] << contributed
contributed_by_type_and_id[type][contributed.id] = contributed
end
end
# Load both parents of the children we just got, and immediately
# contributed objects of that class. all_by_ids_or_children properly
# assigns parents to children, as well
CONTRIBUTED_RELATIONSHIPS.each do |child_type, type|
scope = options[:scopes][type] || type.constantize.scoped
ids = needed_ids_by_type[type]
children = contributed_by_type[child_type]
scope.all_by_ids_or_children(ids, children).each do |contributed|
contributed_by_type_and_id[type][contributed.id] = contributed
end
end
# Assign contributed objects to contributions
contributions.each do |contribution|
type = contribution.contributed_type
id = contribution.contributed_id
contribution.contributed = contributed_by_type_and_id[type][id]
end
end
end