diff --git a/app/models/application_record.rb b/app/models/application_record.rb index a28754a34..396a472ce 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -5,6 +5,20 @@ class ApplicationRecord < ActiveRecord::Base concerning :SearchMethods do class_methods do + def qualified_column_for(attr) + "#{table_name}.#{column_for_attribute(attr).name}" + end + + def where_ilike(attr, value) + where("lower(#{qualified_column_for(attr)}) LIKE ? ESCAPE E'\\\\'", value.mb_chars.downcase.to_escaped_for_sql_like) + end + + # https://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP + # "(?e)" means force use of ERE syntax; see sections 9.7.3.1 and 9.7.3.4. + def where_regex(attr, value) + where("#{qualified_column_for(attr)} ~ ?", "(?e)" + value) + end + def attribute_matches(attribute, value, **options) return all if value.nil? diff --git a/app/models/artist_url.rb b/app/models/artist_url.rb index 68625c9dc..dbeb28fa0 100644 --- a/app/models/artist_url.rb +++ b/app/models/artist_url.rb @@ -6,6 +6,9 @@ class ArtistUrl < ApplicationRecord validate :validate_url_format belongs_to :artist, :touch => true + scope :url_matches, ->(url) { url_attribute_matches(:url, url) } + scope :normalized_url_matches, ->(url) { url_attribute_matches(:normalized_url, url) } + def self.strip_prefixes(url) url.sub(/^[-]+/, "") end @@ -51,6 +54,10 @@ class ArtistUrl < ApplicationRecord q = q.attribute_matches(:artist_id, params[:artist_id]) q = q.attribute_matches(:is_active, params[:is_active]) + q = q.artist_matches(params[:artist]) + q = q.url_matches(params[:url_matches]) + q = q.normalized_url_matches(params[:normalized_url_matches]) + case params[:order] when /\A(id|artist_id|url|normalized_url|is_active|created_at|updated_at)(?:_(asc|desc))?\z/i dir = $2 || :desc @@ -62,6 +69,22 @@ class ArtistUrl < ApplicationRecord q end + def self.artist_matches(params = {}) + return all if params.blank? + where(artist_id: Artist.search(params).reorder(nil)) + end + + def self.url_attribute_matches(attr, url) + if url.blank? + all + elsif url =~ %r!\A/(.*)/\z! + where_regex(attr, $1) + elsif url.include?("*") + where_ilike(attr, url) + else + where(attr => normalize(url)) + end + end def parse_prefix case url diff --git a/app/views/artist_urls/index.html.erb b/app/views/artist_urls/index.html.erb index fd4d498e7..0c86c0a8b 100644 --- a/app/views/artist_urls/index.html.erb +++ b/app/views/artist_urls/index.html.erb @@ -1,6 +1,11 @@