Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeger-Jan van de Weg <zegerjan@gitlab.com>2016-04-16 22:09:08 +0300
committerZeger-Jan van de Weg <zegerjan@gitlab.com>2016-05-06 11:47:11 +0300
commit3bdc57f0a710b3769381ecad7ea4098223ecff56 (patch)
treeabfe22d7d40c7d3e2912d659b045273254767dea /app/models
parent05920a7964a039fd65d6b665c2ebd130d5ef949c (diff)
Create table for award emoji
Diffstat (limited to 'app/models')
-rw-r--r--app/models/award_emoji.rb35
-rw-r--r--app/models/concerns/awardable.rb81
-rw-r--r--app/models/concerns/issuable.rb32
-rw-r--r--app/models/merge_request.rb1
-rw-r--r--app/models/note.rb53
-rw-r--r--app/models/user.rb1
6 files changed, 130 insertions, 73 deletions
diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb
new file mode 100644
index 00000000000..44a9b55a8a6
--- /dev/null
+++ b/app/models/award_emoji.rb
@@ -0,0 +1,35 @@
+class AwardEmoji < ActiveRecord::Base
+ DOWNVOTE_NAME = "thumbsdown".freeze
+ UPVOTE_NAME = "thumbsup".freeze
+
+ include Participable
+
+ belongs_to :awardable, polymorphic: true
+ belongs_to :user
+
+ validates :awardable, :user, presence: true
+ validates :name, presence: true, inclusion: { in: Emoji.emojis_names }
+ validates :name, uniqueness: { scope: [:user, :awardable_type, :awardable_id] }
+
+ participant :user
+
+ scope :downvotes, -> { where(name: DOWNVOTE_NAME) }
+ scope :upvotes, -> { where(name: UPVOTE_NAME) }
+
+ def downvote?
+ self.name == DOWNVOTE_NAME
+ end
+
+ def upvote?
+ self.name == UPVOTE_NAME
+ end
+
+ def to_note_json
+ {
+ valid: valid?,
+ award: true,
+ id: id,
+ name: name
+ }
+ end
+end
diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb
new file mode 100644
index 00000000000..b4e3e9eb3dd
--- /dev/null
+++ b/app/models/concerns/awardable.rb
@@ -0,0 +1,81 @@
+module Awardable
+ extend ActiveSupport::Concern
+
+ included do
+ has_many :award_emoji, as: :awardable, dependent: :destroy
+
+ if self < Participable
+ participant :award_emoji
+ end
+ end
+
+ module ClassMethods
+ def order_upvotes_desc
+ order_votes_desc(AwardEmoji::UPVOTE_NAME)
+ end
+
+ def order_downvotes_desc
+ order_votes_desc(AwardEmoji::DOWNVOTE_NAME)
+ end
+
+ def order_votes_desc(emoji_name)
+ awardable_table = self.arel_table
+ awards_table = AwardEmoji.arel_table
+
+ join_clause = awardable_table.join(awards_table, Arel::Nodes::OuterJoin).on(
+ awards_table[:awardable_id].eq(awardable_table[:id]).and(
+ awards_table[:awardable_type].eq(self.name).and(
+ awards_table[:name].eq(emoji_name)
+ )
+ )
+ ).join_sources
+
+ joins(join_clause).group(awardable_table[:id]).reorder("COUNT(award_emoji.id) DESC")
+ end
+ end
+
+ def grouped_awards(with_thumbs = true)
+ awards = award_emoji.group_by(&:name)
+
+ if with_thumbs
+ awards[AwardEmoji::UPVOTE_NAME] ||= AwardEmoji.none
+ awards[AwardEmoji::DOWNVOTE_NAME] ||= AwardEmoji.none
+ end
+
+ awards
+ end
+
+ def downvotes
+ award_emoji.where(name: AwardEmoji::DOWNVOTE_NAME).count
+ end
+
+ def upvotes
+ award_emoji.where(name: AwardEmoji::UPVOTE_NAME).count
+ end
+
+ def emoji_awardable?
+ true
+ end
+
+ def awarded_emoji?(emoji_name, current_user)
+ award_emoji.where(name: emoji_name, user: current_user).exists?
+ end
+
+ def create_award_emoji(name, current_user)
+ return unless emoji_awardable?
+
+ award_emoji.create(name: name, user: current_user)
+ end
+
+ def remove_award_emoji(name, current_user)
+ award_emoji.where(name: name, user: current_user).destroy_all
+ end
+
+ def toggle_award_emoji(emoji_name, current_user)
+ if awarded_emoji?(emoji_name, current_user)
+ remove_award_emoji(emoji_name, current_user)
+ else
+ create_award_emoji(emoji_name, current_user)
+ end
+ end
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index afa2ca039ae..6af76c97cd3 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -10,6 +10,7 @@ module Issuable
include Mentionable
include Subscribable
include StripAttribute
+ include Awardable
included do
belongs_to :author, class_name: "User"
@@ -99,29 +100,6 @@ module Issuable
order_by(method)
end
end
-
- def order_downvotes_desc
- order_votes_desc('thumbsdown')
- end
-
- def order_upvotes_desc
- order_votes_desc('thumbsup')
- end
-
- def order_votes_desc(award_emoji_name)
- issuable_table = self.arel_table
- note_table = Note.arel_table
-
- join_clause = issuable_table.join(note_table, Arel::Nodes::OuterJoin).on(
- note_table[:noteable_id].eq(issuable_table[:id]).and(
- note_table[:noteable_type].eq(self.name).and(
- note_table[:is_award].eq(true).and(note_table[:note].eq(award_emoji_name))
- )
- )
- ).join_sources
-
- joins(join_clause).group(issuable_table[:id]).reorder("COUNT(notes.id) DESC")
- end
end
def today?
@@ -144,14 +122,6 @@ module Issuable
opened? || reopened?
end
- def downvotes
- notes.awards.where(note: "thumbsdown").count
- end
-
- def upvotes
- notes.awards.where(note: "thumbsup").count
- end
-
def subscribed_without_subscriptions?(user)
participants(user).include?(user)
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index e410febdfff..2cb3e8b0176 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -36,6 +36,7 @@ class MergeRequest < ActiveRecord::Base
include Referable
include Sortable
include Taskable
+ include Awardable
belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project"
belongs_to :source_project, foreign_key: :source_project_id, class_name: "Project"
diff --git a/app/models/note.rb b/app/models/note.rb
index 87ced65c650..b992b2e76f0 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -16,7 +16,6 @@
# system :boolean default(FALSE), not null
# st_diff :text
# updated_by_id :integer
-# is_award :boolean default(FALSE), not null
#
require 'carrierwave/orm/activerecord'
@@ -43,12 +42,9 @@ class Note < ActiveRecord::Base
delegate :name, to: :project, prefix: true
delegate :name, :email, to: :author, prefix: true
- before_validation :set_award!
before_validation :clear_blank_line_code!
validates :note, :project, presence: true
- validates :note, uniqueness: { scope: [:author, :noteable_type, :noteable_id] }, if: ->(n) { n.is_award }
- validates :note, inclusion: { in: Emoji.emojis_names }, if: ->(n) { n.is_award }
validates :line_code, line_code: true, allow_blank: true
# Attachments are deprecated and are handled by Markdown uploader
validates :attachment, file_size: { maximum: :max_attachment_size }
@@ -60,8 +56,6 @@ class Note < ActiveRecord::Base
mount_uploader :attachment, AttachmentUploader
# Scopes
- scope :awards, ->{ where(is_award: true) }
- scope :nonawards, ->{ where(is_award: false) }
scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
scope :inline, ->{ where("line_code IS NOT NULL") }
scope :not_inline, ->{ where(line_code: nil) }
@@ -119,19 +113,6 @@ class Note < ActiveRecord::Base
where(table[:note].matches(pattern))
end
-
- def grouped_awards
- notes = {}
-
- awards.select(:note).distinct.map do |note|
- notes[note.note] = where(note: note.note)
- end
-
- notes["thumbsup"] ||= Note.none
- notes["thumbsdown"] ||= Note.none
-
- notes
- end
end
def cross_reference?
@@ -347,37 +328,25 @@ class Note < ActiveRecord::Base
Event.reset_event_cache_for(self)
end
- def downvote?
- is_award && note == "thumbsdown"
- end
-
- def upvote?
- is_award && note == "thumbsup"
+ def system?
+ read_attribute(:system)
end
def editable?
- !system? && !is_award
+ !system?
end
def cross_reference_not_visible_for?(user)
cross_reference? && referenced_mentionables(user).empty?
end
- # Checks if note is an award added as a comment
- #
- # If note is an award, this method sets is_award to true
- # and changes content of the note to award name.
- #
- # Method is executed as a before_validation callback.
- #
- def set_award!
- return unless awards_supported? && contains_emoji_only?
-
- self.is_award = true
- self.note = award_emoji_name
+ def award_emoji?
+ award_emoji_supported? && contains_emoji_only?
end
- private
+ def create_award_emoji
+ self.noteable.award_emoji(award_emoji_name, author)
+ end
def clear_blank_line_code!
self.line_code = nil if self.line_code.blank?
@@ -389,8 +358,8 @@ class Note < ActiveRecord::Base
diffs.find { |d| d.new_path == self.diff.new_path }
end
- def awards_supported?
- (for_issue? || for_merge_request?) && !for_diff_line?
+ def award_emoji_supported?
+ noteable.is_a?(Awardable) && !for_diff_line?
end
def contains_emoji_only?
@@ -399,6 +368,6 @@ class Note < ActiveRecord::Base
def award_emoji_name
original_name = note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1]
- AwardEmoji.normilize_emoji_name(original_name)
+ Gitlab::AwardEmoji.normilize_emoji_name(original_name)
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 031315debd7..52f2904f450 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -144,6 +144,7 @@ class User < ActiveRecord::Base
has_many :builds, dependent: :nullify, class_name: 'Ci::Build'
has_many :todos, dependent: :destroy
has_many :notification_settings, dependent: :destroy
+ has_many :award_emoji, as: :awardable, dependent: :destroy
#
# Validations