From c06af060f90f8a0f08efb51705c240d49a0c85cd Mon Sep 17 00:00:00 2001 From: evazion Date: Sat, 15 Sep 2018 11:44:05 -0500 Subject: [PATCH] artist urls: add artist, url_matches search params to /artist_urls. --- app/models/application_record.rb | 14 ++++++++++++++ app/models/artist_url.rb | 23 +++++++++++++++++++++++ app/views/artist_urls/index.html.erb | 5 +++++ 3 files changed, 42 insertions(+) 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 @@
<%= simple_form_for(:search, url: artist_urls_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> + <%= f.simple_fields_for :artist do |fa| %> + <%= fa.input :name, label: "Artist Name", input_html: { value: params.dig(:search, :artist, :name), "data-autocomplete": "artist" } %> + <% end %> + <%= f.input :url_matches, label: "URL", input_html: { value: params[:search][:url_matches] } %> + <%= f.input :normalized_url_matches, label: "Normalized URL", input_html: { value: params[:search][:normalized_url_matches] } %> <%= f.input :is_active, label: "Active?", collection: [["Yes", true], ["No", false]], include_blank: true, selected: params[:search][:is_active] %> <%= f.input :order, collection: [["ID", "id"], ["Created", "created_at"], ["Updated", "updated_at"]], selected: params[:search][:order] %> <%= f.submit "Search" %>