Skip to content

Commit

Permalink
Allow overriding of existing fields/attributes.
Browse files Browse the repository at this point in the history
This gives people the option of changing the data of the default templates fields and attributes. I suspect the cases for this are very rare, but one such situation is when anonymous models are in play, as requested by @kalsan in #1172.
  • Loading branch information
pat committed Jun 24, 2020
1 parent 16f2e66 commit f33642d
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 40 deletions.
8 changes: 4 additions & 4 deletions lib/thinking_sphinx/active_record/interpreter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ def group_by(*columns)
end

def has(*columns)
__source.attributes += build_properties(
build_properties(
::ThinkingSphinx::ActiveRecord::Attribute, columns
)
).each { |attribute| __source.add_attribute attribute }
end

def indexes(*columns)
__source.fields += build_properties(
build_properties(
::ThinkingSphinx::ActiveRecord::Field, columns
)
).each { |field| __source.add_field field }
end

def join(*columns)
Expand Down
12 changes: 12 additions & 0 deletions lib/thinking_sphinx/active_record/sql_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ def adapter
@adapter ||= DatabaseAdapters.adapter_for(@model)
end

def add_attribute(attribute)
attributes.delete_if { |existing| existing.name == attribute.name }

attributes << attribute
end

def add_field(field)
fields.delete_if { |existing| existing.name == field.name }

fields << field
end

def delta_processor
options[:delta_processor].try(:new, adapter, @options[:delta_options] || {})
end
Expand Down
4 changes: 2 additions & 2 deletions lib/thinking_sphinx/active_record/sql_source/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ def apply
private

def add_attribute(column, name, type, options = {})
source.attributes << ThinkingSphinx::ActiveRecord::Attribute.new(
source.add_attribute ThinkingSphinx::ActiveRecord::Attribute.new(
source.model, ThinkingSphinx::ActiveRecord::Column.new(column),
options.merge(:as => name, :type => type)
)
end

def add_field(column, name, options = {})
source.fields << ThinkingSphinx::ActiveRecord::Field.new(
source.add_field ThinkingSphinx::ActiveRecord::Field.new(
source.model, ThinkingSphinx::ActiveRecord::Column.new(column),
options.merge(:as => name)
)
Expand Down
4 changes: 4 additions & 0 deletions lib/thinking_sphinx/real_time/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ def initialize(reference, options = {})
end

def add_attribute(attribute)
@attributes.delete_if { |existing| existing.name == attribute.name }

@attributes << attribute
end

def add_field(field)
@fields.delete_if { |existing| existing.name == field.name }

@fields << field
end

Expand Down
14 changes: 8 additions & 6 deletions lib/thinking_sphinx/real_time/interpreter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ class ThinkingSphinx::RealTime::Interpreter <

def has(*columns)
options = columns.extract_options!
@index.attributes += columns.collect { |column|

columns.collect { |column|
::ThinkingSphinx::RealTime::Attribute.new column, options
}
}.each { |attribute| @index.add_attribute attribute }
end

def indexes(*columns)
options = columns.extract_options!
@index.fields += columns.collect { |column|

columns.collect { |column|
::ThinkingSphinx::RealTime::Field.new column, options
}
}.each { |field| @index.add_field field }

append_sortable_attributes columns, options if options[:sortable]
end
Expand All @@ -39,14 +41,14 @@ def where(condition)
def append_sortable_attributes(columns, options)
options = options.except(:sortable).merge(:type => :string)

@index.attributes += columns.collect { |column|
columns.collect { |column|
aliased_name = options[:as]
aliased_name ||= column.__name.to_sym if column.respond_to?(:__name)
aliased_name ||= column

options[:as] = "#{aliased_name}_sort".to_sym

::ThinkingSphinx::RealTime::Attribute.new column, options
}
}.each { |attribute| @index.add_attribute attribute }
end
end
29 changes: 15 additions & 14 deletions spec/thinking_sphinx/active_record/interpreter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@
let(:block) { Proc.new { } }

before :each do
allow(ThinkingSphinx::ActiveRecord::SQLSource).to receive_messages :new => source
allow(source).to receive_messages :model => model
allow(ThinkingSphinx::ActiveRecord::SQLSource).to receive_messages(
:new => source
)

allow(source).to receive_messages(
:model => model, :add_attribute => nil, :add_field => nil
)
end

describe '.translate!' do
Expand Down Expand Up @@ -94,17 +99,15 @@
end

it "adds an attribute to the source" do
instance.has column
expect(source).to receive(:add_attribute).with(attribute)

expect(source.attributes).to include(attribute)
instance.has column
end

it "adds multiple attributes when passed multiple columns" do
instance.has column, column
expect(source).to receive(:add_attribute).with(attribute).twice

expect(source.attributes.select { |saved_attribute|
saved_attribute == attribute
}.length).to eq(2)
instance.has column, column
end
end

Expand Down Expand Up @@ -144,17 +147,15 @@
end

it "adds a field to the source" do
instance.indexes column
expect(source).to receive(:add_field).with(field)

expect(source.fields).to include(field)
instance.indexes column
end

it "adds multiple fields when passed multiple columns" do
instance.indexes column, column
expect(source).to receive(:add_field).with(field).twice

expect(source.fields.select { |saved_field|
saved_field == field
}.length).to eq(2)
instance.indexes column, column
end
end

Expand Down
38 changes: 38 additions & 0 deletions spec/thinking_sphinx/active_record/sql_source_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,44 @@
end
end

describe '#add_attribute' do
let(:attribute) { double('attribute', name: 'my_attribute') }

it "appends attributes to the collection" do
source.add_attribute attribute

expect(source.attributes.collect(&:name)).to include('my_attribute')
end

it "replaces attributes with the same name" do
source.add_attribute double('attribute', name: 'my_attribute')
source.add_attribute attribute

matching = source.attributes.select { |attr| attr.name == attribute.name }

expect(matching).to eq([attribute])
end
end

describe '#add_field' do
let(:field) { double('field', name: 'my_field') }

it "appends fields to the collection" do
source.add_field field

expect(source.fields.collect(&:name)).to include('my_field')
end

it "replaces fields with the same name" do
source.add_field double('field', name: 'my_field')
source.add_field field

matching = source.fields.select { |fld| fld.name == field.name }

expect(matching).to eq([field])
end
end

describe '#attributes' do
it "has the internal id attribute by default" do
expect(source.attributes.collect(&:name)).to include('sphinx_internal_id')
Expand Down
38 changes: 38 additions & 0 deletions spec/thinking_sphinx/real_time/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,44 @@
allow(ThinkingSphinx::Configuration).to receive_messages :instance => config
end

describe '#add_attribute' do
let(:attribute) { double('attribute', name: 'my_attribute') }

it "appends attributes to the collection" do
index.add_attribute attribute

expect(index.attributes.collect(&:name)).to include('my_attribute')
end

it "replaces attributes with the same name" do
index.add_attribute double('attribute', name: 'my_attribute')
index.add_attribute attribute

matching = index.attributes.select { |attr| attr.name == attribute.name }

expect(matching).to eq([attribute])
end
end

describe '#add_field' do
let(:field) { double('field', name: 'my_field') }

it "appends fields to the collection" do
index.add_field field

expect(index.fields.collect(&:name)).to include('my_field')
end

it "replaces fields with the same name" do
index.add_field double('field', name: 'my_field')
index.add_field field

matching = index.fields.select { |fld| fld.name == field.name }

expect(matching).to eq([field])
end
end

describe '#attributes' do
it "has the internal id attribute by default" do
expect(index.attributes.collect(&:name)).to include('sphinx_internal_id')
Expand Down
28 changes: 14 additions & 14 deletions spec/thinking_sphinx/real_time/interpreter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
let(:index) { Struct.new(:attributes, :fields, :options).new([], [], {}) }
let(:block) { Proc.new { } }

before :each do
allow(index).to receive_messages(:add_attribute => nil, :add_field => nil)
end

describe '.translate!' do
let(:instance) { double('interpreter', :translate! => true) }

Expand Down Expand Up @@ -51,17 +55,15 @@
end

it "adds an attribute to the index" do
instance.has column
expect(index).to receive(:add_attribute).with(attribute)

expect(index.attributes).to include(attribute)
instance.has column
end

it "adds multiple attributes when passed multiple columns" do
instance.has column, column
expect(index).to receive(:add_attribute).with(attribute).twice

expect(index.attributes.select { |saved_attribute|
saved_attribute == attribute
}.length).to eq(2)
instance.has column, column
end
end

Expand All @@ -88,17 +90,15 @@
end

it "adds a field to the index" do
instance.indexes column
expect(index).to receive(:add_field).with(field)

expect(index.fields).to include(field)
instance.indexes column
end

it "adds multiple fields when passed multiple columns" do
instance.indexes column, column
expect(index).to receive(:add_field).with(field).twice

expect(index.fields.select { |saved_field|
saved_field == field
}.length).to eq(2)
instance.indexes column, column
end

context 'sortable' do
Expand Down Expand Up @@ -135,9 +135,9 @@
end

it "adds an attribute to the index" do
instance.indexes column, :sortable => true
expect(index).to receive(:add_attribute).with(attribute)

expect(index.attributes).to include(attribute)
instance.indexes column, :sortable => true
end
end
end
Expand Down

0 comments on commit f33642d

Please sign in to comment.