Use scopes for better query performance

This commit is contained in:
Alberto Miedes Garcés
2017-06-01 20:04:51 +02:00
parent 18db68a430
commit 9ec8b166d7
11 changed files with 14 additions and 24 deletions

View File

@@ -26,8 +26,7 @@ class Comment < ActiveRecord::Base
scope :with_visible_author, -> { joins(:user).where("users.hidden_at IS NULL") }
scope :not_as_admin_or_moderator, -> { where("administrator_id IS NULL").where("moderator_id IS NULL")}
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
def self.public_for_api
scope :public_for_api, -> do
joins("FULL OUTER JOIN debates ON commentable_type = 'Debate' AND commentable_id = debates.id").
joins("FULL OUTER JOIN proposals ON commentable_type = 'Proposal' AND commentable_id = proposals.id").
where("commentable_type = 'Proposal' AND proposals.hidden_at IS NULL OR commentable_type = 'Debate' AND debates.hidden_at IS NULL")

View File

@@ -39,6 +39,7 @@ class Debate < ActiveRecord::Base
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
scope :last_week, -> { where("created_at >= ?", 7.days.ago)}
scope :featured, -> { where("featured_at is not null")}
scope :public_for_api, -> { all }
# Ahoy setup
visitable # Ahoy will automatically assign visit_id on create

View File

@@ -8,6 +8,8 @@ class Geozone < ActiveRecord::Base
has_many :users
validates :name, presence: true
scope :public_for_api, -> { all }
def self.names
Geozone.pluck(:name)
end

View File

@@ -53,6 +53,7 @@ class Proposal < ActiveRecord::Base
scope :retired, -> { where.not(retired_at: nil) }
scope :not_retired, -> { where(retired_at: nil) }
scope :successful, -> { where("cached_votes_up >= ?", Proposal.votes_needed_for_success) }
scope :public_for_api, -> { all }
def to_param
"#{id}-#{title}".parameterize

View File

@@ -10,9 +10,7 @@ class ProposalNotification < ActiveRecord::Base
validates :proposal, presence: true
validate :minimum_interval
def self.public_for_api
joins(:proposal).where("proposals.hidden_at IS NULL")
end
scope :public_for_api, -> { joins(:proposal).where("proposals.hidden_at IS NULL") }
def minimum_interval
return true if proposal.try(:notifications).blank?

View File

@@ -59,6 +59,7 @@ class User < ActiveRecord::Base
scope :email_digest, -> { where(email_digest: true) }
scope :active, -> { where(erased_at: nil) }
scope :erased, -> { where.not(erased_at: nil) }
scope :public_for_api, -> { all }
before_validation :clean_document_number
@@ -287,15 +288,15 @@ class User < ActiveRecord::Base
delegate :can?, :cannot?, to: :ability
def public_proposals
public_activity? ? proposals : []
public_activity? ? proposals : User.none
end
def public_debates
public_activity? ? debates : []
public_activity? ? debates : User.none
end
def public_comments
public_activity? ? comments : []
public_activity? ? comments : User.none
end
private

View File

@@ -2,7 +2,7 @@ class Vote < ActsAsVotable::Vote
include Graphqlable
def self.public_for_api
scope :public_for_api, -> do
joins("FULL OUTER JOIN debates ON votable_type = 'Debate' AND votable_id = debates.id").
joins("FULL OUTER JOIN proposals ON votable_type = 'Proposal' AND votable_id = proposals.id").
joins("FULL OUTER JOIN comments ON votable_type = 'Comment' AND votable_id = comments.id").
@@ -16,4 +16,5 @@ class Vote < ActsAsVotable::Vote
) \
)")
end
end

View File

@@ -1 +0,0 @@
require 'active_record_extensions'

View File

@@ -44,7 +44,7 @@ module ActsAsTaggableOn
ActsAsTaggableOn::Tag.where('taggings.taggable_type' => 'SpendingProposal').includes(:taggings).order(:name).uniq
end
def self.public_for_api
scope :public_for_api, -> do
find_by_sql(%|
SELECT *
FROM tags

View File

@@ -1,12 +0,0 @@
module PublicForApi
extend ActiveSupport::Concern
class_methods do
def public_for_api
all
end
end
end
ActiveRecord::Base.send(:include, PublicForApi)

View File

@@ -50,7 +50,7 @@ module GraphQL
when :multiple_association
field_type = field_type.first
connection(field_name, -> { created_types[field_type].connection_type }, max_page_size: 50, complexity: 1000) do
resolve -> (object, arguments, context) { field_type.public_for_api & object.send(field_name) }
resolve -> (object, arguments, context) { object.send(field_name).public_for_api }
end
end
end