Fixed ransack admin search

This commit is contained in:
Sergei Tsoganov 2023-04-06 13:54:03 +03:00
parent ae384e4e64
commit aa8d8c35e8
9 changed files with 34 additions and 20 deletions

View file

@ -26,7 +26,7 @@ module Admin
respond_to do |format| respond_to do |format|
format.html { render page } format.html { render page }
format.csv do format.csv do
raw_csv = CsvGenerator.generate_csv(@q.result) raw_csv = CsvGenerator.generate_csv(@q.result(distinct: true))
send_data raw_csv, send_data raw_csv,
filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv",
type: "#{Mime[:csv]}; charset=utf-8" type: "#{Mime[:csv]}; charset=utf-8"

View file

@ -5,27 +5,21 @@ module Admin
before_action :set_domain, only: %i[show edit update download keep] before_action :set_domain, only: %i[show edit update download keep]
authorize_resource authorize_resource
# rubocop:disable Metrics/MethodLength
def index def index
params[:q] ||= {} params[:q] ||= {}
domains = if params[:statuses_contains] domains = Domain.includes(:registrar, :registrant).joins(:registrar, :registrant)
Domain.includes(:registrar, :registrant).where( p = params[:statuses_contains]
"domains.statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}" domains = domains.where('domains.statuses @> ?::varchar[]', "{#{p.join(',')}}") if p.present?
)
else
Domain.includes(:registrar, :registrant)
end
normalize_search_parameters do normalize_search_parameters do
@q = domains.ransack(PartialSearchFormatter.format(params[:q])) @q = domains.ransack(PartialSearchFormatter.format(params[:q]))
@domains = @q.result.page(params[:page]) @domains = @q.result(distinct: true).page(params[:page])
end end
@domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i.positive? @domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i.positive?
render_by_format('admin/domains/index', 'domains') render_by_format('admin/domains/index', 'domains')
end end
# rubocop:enable Metrics/MethodLength
def show def show
# Validation is needed to warn users # Validation is needed to warn users

View file

@ -188,7 +188,7 @@ class Contact < ApplicationRecord
end end
def ransackable_attributes(auth_object = nil) def ransackable_attributes(auth_object = nil)
super authorizable_ransackable_attributes
end end
def search_by_query(query) def search_by_query(query)

View file

@ -246,11 +246,11 @@ class Domain < ApplicationRecord
class << self class << self
def ransackable_associations(auth_object = nil) def ransackable_associations(auth_object = nil)
super authorizable_ransackable_associations
end end
def ransackable_attributes(auth_object = nil) def ransackable_attributes(auth_object = nil)
super authorizable_ransackable_attributes
end end
def nameserver_required? def nameserver_required?
@ -755,12 +755,14 @@ class Domain < ApplicationRecord
def as_csv_row def as_csv_row
[ [
name, name,
registrant_name, "#{registrant_name}, #{registrant_ident_info}",
valid_to.to_formatted_s(:db), valid_to.to_formatted_s(:db),
registrar, registrar,
created_at.to_formatted_s(:db), created_at.to_formatted_s(:db),
statuses, statuses,
contacts.pluck(:code), admin_contacts.map { |c| "#{c.name}, #{c.code}, #{ApplicationController.helpers.ident_for(c)}" },
tech_contacts.map { |c| "#{c.name}, #{c.code}, #{ApplicationController.helpers.ident_for(c)}" },
nameservers.pluck(:hostname),
force_delete_date, force_delete_date,
force_delete_data, force_delete_data,
] ]
@ -783,10 +785,14 @@ class Domain < ApplicationRecord
contact.try(:name) || 'Deleted' contact.try(:name) || 'Deleted'
end end
def registrant_ident_info
return ApplicationController.helpers.ident_for(registrant) if registrant
end
def self.csv_header def self.csv_header
[ [
'Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at', 'Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at',
'Statuses', 'Contacts code', 'Force delete date', 'Force delete data' 'Statuses', 'Admin. contacts', 'Tech. contacts', 'Nameservers', 'Force delete date', 'Force delete data'
] ]
end end

View file

@ -86,6 +86,10 @@ class Nameserver < ApplicationRecord
def hostnames def hostnames
pluck(:hostname) pluck(:hostname)
end end
def ransackable_attributes(auth_object = nil)
authorizable_ransackable_attributes
end
end end
private private

View file

@ -51,6 +51,14 @@ class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength
self.ignored_columns = %w[legacy_id] self.ignored_columns = %w[legacy_id]
class << self class << self
def ransackable_associations(auth_object = nil)
super
end
def ransackable_attributes(auth_object = nil)
authorizable_ransackable_attributes
end
def ordered def ordered
order(name: :asc) order(name: :asc)
end end

View file

@ -5,7 +5,7 @@ class PartialSearchFormatter
search_params.each do |key, value| search_params.each do |key, value|
next unless key.include?('matches') && value.present? next unless key.include?('matches') && value.present?
search_params[key] = "%#{value}%" search_params[key] = value =~ /\A\*.*\*\z/ ? value.gsub(/\A\*|\*\z/, '') : "%#{value}%"
end end
search_params search_params

View file

@ -3,7 +3,7 @@ class DomainNameValidator < ActiveModel::EachValidator
# rubocop:disable Metrics/LineLength # rubocop:disable Metrics/LineLength
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
if !self.class.validate_format(value) if !self.class.validate_format(value)
record.errors[attribute] << (options[:message] || record.errors.generate_message(attribute, :invalid)) record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :invalid))
elsif !self.class.validate_blocked(value) elsif !self.class.validate_blocked(value)
record.errors.add(:base, :domain_name_blocked) record.errors.add(:base, :domain_name_blocked)
end end
@ -12,6 +12,7 @@ class DomainNameValidator < ActiveModel::EachValidator
class << self class << self
def validate_format(value) def validate_format(value)
return true unless value return true unless value
value = value.mb_chars.downcase.strip value = value.mb_chars.downcase.strip
origins = DNS::Zone.origins origins = DNS::Zone.origins
@ -25,6 +26,7 @@ class DomainNameValidator < ActiveModel::EachValidator
if value[2] == '-' && value[3] == '-' if value[2] == '-' && value[3] == '-'
regexp = /\Axn--[a-zA-Z0-9-]{0,59}\.#{general_domains}\z/ regexp = /\Axn--[a-zA-Z0-9-]{0,59}\.#{general_domains}\z/
return false unless value.match?(regexp) return false unless value.match?(regexp)
value = SimpleIDN.to_unicode(value).mb_chars.downcase.strip value = SimpleIDN.to_unicode(value).mb_chars.downcase.strip
end end

View file

@ -1,5 +1,5 @@
<tr> <tr>
<td><%= link_to domain, admin_domain_path(domain) %></td> <td style="word-break:break-all;"><%= link_to domain, admin_domain_path(domain) %></td>
<td><%= link_to domain.registrant, admin_contact_path(domain.registrant) %></td> <td><%= link_to domain.registrant, admin_contact_path(domain.registrant) %></td>
<td><%= l domain.expire_time %></td> <td><%= l domain.expire_time %></td>
<td><%= link_to domain.registrar, admin_registrar_path(domain.registrar) %></td> <td><%= link_to domain.registrar, admin_registrar_path(domain.registrar) %></td>