8a72f5c427
This commit adds the module `FromUnion`, which provides the class method `from_union`. This simplifies the process of selecting data from the result of a UNION, and reduces the likelihood of making mistakes. As a result, instead of this: union = Gitlab::SQL::Union.new([foo, bar]) Foo.from("(#{union.to_sql}) #{Foo.table_name}") We can now write this instead: Foo.from_union([foo, bar]) This commit also includes some changes to make this new setup work properly. For example, a bug in Rails 4 (https://github.com/rails/rails/issues/24193) would break the use of `from("sub-query-here").includes(:relation)` in certain cases. There was also a CI query which appeared to repeat a lot of conditions from an outer query on an inner query, which isn't necessary. Finally, we include a RuboCop cop to ensure developers use this new module, instead of using Gitlab::SQL::Union directly. Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/51307
55 lines
1.8 KiB
Ruby
55 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Badge < ActiveRecord::Base
|
|
include FromUnion
|
|
|
|
# This structure sets the placeholders that the urls
|
|
# can have. This hash also sets which action to ask when
|
|
# the placeholder is found.
|
|
PLACEHOLDERS = {
|
|
'project_path' => :full_path,
|
|
'project_id' => :id,
|
|
'default_branch' => :default_branch,
|
|
'commit_sha' => ->(project) { project.commit&.sha }
|
|
}.freeze
|
|
|
|
# This regex is built dynamically using the keys from the PLACEHOLDER struct.
|
|
# So, we can easily add new placeholder just by modifying the PLACEHOLDER hash.
|
|
# This regex will build the new PLACEHOLDER_REGEX with the new information
|
|
PLACEHOLDERS_REGEX = /(#{PLACEHOLDERS.keys.join('|')})/.freeze
|
|
|
|
default_scope { order_created_at_asc }
|
|
|
|
scope :order_created_at_asc, -> { reorder(created_at: :asc) }
|
|
|
|
validates :link_url, :image_url, url: { protocols: %w(http https) }
|
|
validates :type, presence: true
|
|
|
|
def rendered_link_url(project = nil)
|
|
build_rendered_url(link_url, project)
|
|
end
|
|
|
|
def rendered_image_url(project = nil)
|
|
build_rendered_url(image_url, project)
|
|
end
|
|
|
|
private
|
|
|
|
def build_rendered_url(url, project = nil)
|
|
return url unless valid? && project
|
|
|
|
Gitlab::StringPlaceholderReplacer.replace_string_placeholders(url, PLACEHOLDERS_REGEX) do |arg|
|
|
replace_placeholder_action(PLACEHOLDERS[arg], project)
|
|
end
|
|
end
|
|
|
|
# The action param represents the :symbol or Proc to call in order
|
|
# to retrieve the return value from the project.
|
|
# This method checks if it is a Proc and use the call method, and if it is
|
|
# a symbol just send the action
|
|
def replace_placeholder_action(action, project)
|
|
return unless project
|
|
|
|
action.is_a?(Proc) ? action.call(project) : project.public_send(action) # rubocop:disable GitlabSecurity/PublicSend
|
|
end
|
|
end
|