Use class attributes properly so that inheritance is respected

This fixes two bugs:

1. Subclasses were not properly inheriting their parents' Ransack
   aliases in Mongoid because each class defined its very own set of
   aliases.
2. In Active Record, Ransack aliases were defined in such a way that the
   parent's (and grandparent's, etc.) aliases were overwritten by the
   child, meaning that all aliases were ultimately kept on
   ActiveRecord::Base. This has the unfortunate effect of enforcing
   uniqueness of Ransack alias names across all models rather than per
   model. Depending on the load order of models, earlier definitions of
   an alias in other models would be clobbered.
This commit is contained in:
Steve Richert 2016-08-26 13:48:59 -04:00
parent 9340582092
commit e55e99fe89
6 changed files with 56 additions and 18 deletions

View File

@ -23,7 +23,8 @@ module Ransack
end
def ransack_alias(new_name, old_name)
self._ransack_aliases.store(new_name.to_s, old_name.to_s)
self._ransack_aliases = _ransack_aliases.merge new_name.to_s =>
old_name.to_s
end
# Ransackable_attributes, by default, returns all column names

View File

@ -8,6 +8,10 @@ module Ransack
extend ActiveSupport::Concern
included do
class_attribute :_ransackers
class_attribute :_ransack_aliases
self._ransackers ||= {}
self._ransack_aliases ||= {}
end
class ColumnWrapper < SimpleDelegator
@ -33,22 +37,6 @@ module Ransack
end
module ClassMethods
def _ransack_aliases
@_ransack_aliases ||= {}
end
def _ransack_aliases=(value)
@_ransack_aliases = value
end
def _ransackers
@_ransackers ||= {}
end
def _ransackers=(value)
@_ransackers = value
end
def ransack(params = {}, options = {})
params = params.presence || {}
Search.new(self, params ? params.delete_if {
@ -58,7 +46,8 @@ module Ransack
alias_method :search, :ransack
def ransack_alias(new_name, old_name)
self._ransack_aliases.store(new_name.to_s, old_name.to_s)
self._ransack_aliases = _ransack_aliases.merge new_name.to_s =>
old_name.to_s
end
def ransacker(name, opts = {}, &block)

View File

@ -65,6 +65,27 @@ module Ransack
s = Person.ransack(term_cont: 'nomatch')
expect(s.result.to_a).to eq []
end
it 'makes aliases available to subclasses' do
yngwie = Musician.create!(name: 'Yngwie Malmsteen')
musicians = Musician.ransack(term_cont: 'ngw').result
expect(musicians).to eq([yngwie])
end
it 'handles naming collisions gracefully' do
frank = Person.create!(name: 'Frank Stallone')
people = Person.ransack(term_cont: 'allon').result
expect(people).to eq([frank])
Class.new(Article) do
ransack_alias :term, :title
end
people = Person.ransack(term_cont: 'allon').result
expect(people).to eq([frank])
end
end
describe '#ransacker' do

View File

@ -63,6 +63,9 @@ class Person
end
end
class Musician < Person
end
class Article
include Mongoid::Document

View File

@ -190,6 +190,27 @@ module Ransack
s = Person.ransack(daddy_eq: 'Drake')
expect(s.result.to_a).to eq []
end
it 'makes aliases available to subclasses' do
yngwie = Musician.create!(name: 'Yngwie Malmsteen')
musicians = Musician.ransack(term_cont: 'ngw').result
expect(musicians).to eq([yngwie])
end
it 'handles naming collisions gracefully' do
frank = Person.create!(name: 'Frank Stallone')
people = Person.ransack(term_cont: 'allon').result
expect(people).to eq([frank])
Class.new(Article) do
ransack_alias :term, :title
end
people = Person.ransack(term_cont: 'allon').result
expect(people).to eq([frank])
end
end
describe '#ransacker' do

View File

@ -127,6 +127,9 @@ class Person < ActiveRecord::Base
end
end
class Musician < Person
end
class Article < ActiveRecord::Base
belongs_to :person
has_many :comments