diff --git a/.travis.yml b/.travis.yml index aaa4c9896..113979c79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ rvm: - 2.3.8 - 2.4.5 - 2.5.3 -- 2.6.0 +- 2.6.1 addons: apt: packages: @@ -13,7 +13,8 @@ addons: before_install: - pip install --upgrade --user awscli - gem update --system -- gem install bundler +- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true +- gem install bundler -v '< 2' before_script: - mysql -e 'create database thinking_sphinx;' > /dev/null - psql -c 'create database thinking_sphinx;' -U postgres >/dev/null @@ -32,10 +33,12 @@ env: - DATABASE=mysql2 SPHINX_VERSION=3.0.3 SPHINX_ENGINE=sphinx - DATABASE=postgresql SPHINX_VERSION=3.0.3 SPHINX_ENGINE=sphinx - DATABASE=mysql2 SPHINX_VERSION=3.1.1 SPHINX_ENGINE=sphinx - - DATABASE=mysql2 SPHINX_VERSION=2.6.3 SPHINX_ENGINE=manticore - - DATABASE=postgresql SPHINX_VERSION=2.6.3 SPHINX_ENGINE=manticore - - DATABASE=mysql2 SPHINX_VERSION=2.7.4 SPHINX_ENGINE=manticore - - DATABASE=postgresql SPHINX_VERSION=2.7.4 SPHINX_ENGINE=manticore + - DATABASE=mysql2 SPHINX_VERSION=2.6.4 SPHINX_ENGINE=manticore + - DATABASE=postgresql SPHINX_VERSION=2.6.4 SPHINX_ENGINE=manticore + - DATABASE=mysql2 SPHINX_VERSION=2.7.5 SPHINX_ENGINE=manticore + - DATABASE=postgresql SPHINX_VERSION=2.7.5 SPHINX_ENGINE=manticore + - DATABASE=mysql2 SPHINX_VERSION=2.8.1 SPHINX_ENGINE=manticore + - DATABASE=postgresql SPHINX_VERSION=2.8.1 SPHINX_ENGINE=manticore # - DATABASE=postgresql SPHINX_VERSION=3.1.1 SPHINX_ENGINE=sphinx sudo: false addons: diff --git a/Appraisals b/Appraisals index c0dfdd6fd..e70914fa9 100644 --- a/Appraisals +++ b/Appraisals @@ -41,4 +41,10 @@ appraise 'rails_5_2' do gem 'rails', '~> 5.2.0' gem 'mysql2', '~> 0.5.0', :platform => :ruby gem 'pg', '~> 1.0', :platform => :ruby -end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.3 +end if RUBY_PLATFORM != 'java' + +appraise 'rails_6_0' do + gem 'rails', '~> 6.0.0.beta1' + gem 'mysql2', '~> 0.5.0', :platform => :ruby + gem 'pg', '~> 1.0', :platform => :ruby +end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.5 diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index d92559390..47b3c6506 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -2,6 +2,26 @@ All notable changes to this project (at least, from v3.0.0 onwards) are documented in this file. +## 4.2.0 - 2019-03-09 + +### Added + +* Allow changing the default encoding for MySQL database connections from utf8 to something else via the `mysql_encoding` setting in `config/thinking_sphinx.yml`. In the next significant release, the default will change to utf8mb4 (which is supported in MySQL 5.5.3 and newer). +* Added Rails 6.0 and Manticore 2.8 to the test matrix. + +### Changed + +* Use Arel's SQL literals for generated order clauses, to avoid warnings from Rails 6. + +### Fixed + +* Fix usage of alternative primary keys in update and deletion callbacks and attribute access. +* Ensure `respond_to?` takes Sphinx scopes into account ([Jonathan del Strother](https://github.com/jdelstrother) in [#1124](https://github.com/pat/thinking-sphinx/pull/1124)). +* Add `:excerpts` as a known option for search requests. +* Fix depolymorphed association join construction with Rails 6.0.0.beta2. +* Reset ThinkingSphinx::Configuration's cached values when Rails reloads, to avoid holding onto stale references to ActiveRecord models ([#1125](https://github.com/pat/thinking-sphinx/issues/1125)). +* Don't join against associations in `sql_query` if they're only used by query-sourced properties ([Hans de Graaff](https://github.com/graaff) in [#1127](https://github.com/pat/thinking-sphinx/pull/1127)). + ## 4.1.0 - 2018-12-28 [Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v4.1.0) diff --git a/README.textile b/README.textile index 91e923aa2..71f0cee09 100644 --- a/README.textile +++ b/README.textile @@ -1,6 +1,6 @@ h1. Thinking Sphinx -Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v4.1.0. +Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v4.2.0. h2. Upgrading @@ -14,7 +14,7 @@ It's a gem, so install it like you would any other gem. You will also need to sp
gem 'mysql2', '~> 0.3', :platform => :ruby
gem 'jdbc-mysql', '~> 5.1.35', :platform => :jruby
-gem 'thinking-sphinx', '~> 4.1'
+gem 'thinking-sphinx', '~> 4.2'
The MySQL gems mentioned are required for connecting to Sphinx, so please include it even when you're using PostgreSQL for your database. If you're using JRuby with a version of Sphinx prior to 2.2.11, there is "currently an issue with Sphinx and jdbc-mysql 5.1.36 or newer":http://sphinxsearch.com/forum/view.html?id=13939, so you'll need to stick to nothing more recent than 5.1.35, or upgrade Sphinx.
@@ -29,10 +29,10 @@ h2. Requirements
The current release of Thinking Sphinx works with the following versions of its dependencies:
|_. Library |_. Minimum |_. Tested Against |
-| Ruby | v2.3 | v2.3.8, v2.4.5, v2.5.3, v2.6.0 |
+| Ruby | v2.3 | v2.3.8, v2.4.5, v2.5.3, v2.6.1 |
| Sphinx | v2.1.2 | v2.1.9, v2.2.11, v3.0.3, v3.1.1 |
-| Manticore | v2.6.3 | v2.6.3, v2.7.4 |
-| ActiveRecord | v3.2 | v3.2, v4.0, v4.1, v4.2, v5.0, v5.1, v5.2 |
+| Manticore | v2.6.3 | v2.6.4, v2.7.5, v2.8.1 |
+| ActiveRecord | v3.2 | v3.2..v6.0 |
It _might_ work with older versions of Ruby, but it's highly recommended to update to a supported release.
@@ -52,7 +52,7 @@ If you want ActiveRecord 3.1 support, then refer to the 3.0.x releases of Thinki
h3. Ruby
-You'll need either the standard Ruby (v2.2 or newer) or JRuby (9.1 or newer).
+You'll need either the standard Ruby (v2.3 or newer) or JRuby (9.1 or newer).
h3. Database Versions
@@ -81,4 +81,4 @@ You can then run the unit tests with @rake spec:unit@, the acceptance tests with
h2. Licence
-Copyright (c) 2007-2018, Thinking Sphinx is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to "all who have contributed patches":https://github.com/pat/thinking-sphinx/contributors.
+Copyright (c) 2007-2019, Thinking Sphinx is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to "all who have contributed patches":https://github.com/pat/thinking-sphinx/contributors.
diff --git a/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb b/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb
index 3b08aa2ca..a60cdec57 100644
--- a/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb
+++ b/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb
@@ -19,7 +19,9 @@ def delete_from_sphinx
return if ThinkingSphinx::Callbacks.suspended? || instance.new_record?
indices.each { |index|
- ThinkingSphinx::Deletion.perform index, instance.id
+ ThinkingSphinx::Deletion.perform(
+ index, instance.public_send(index.primary_key)
+ )
}
end
diff --git a/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb b/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb
index 7c37bfe8b..042632242 100644
--- a/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb
+++ b/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb
@@ -55,7 +55,9 @@ def update(index)
return if attributes.empty?
sphinxql = Riddle::Query.update(
- index.name, index.document_id_for_key(instance.id), attributes
+ index.name,
+ index.document_id_for_key(instance.public_send(index.primary_key)),
+ attributes
)
ThinkingSphinx::Connection.take do |connection|
connection.execute(sphinxql)
diff --git a/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb b/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb
index 2d3f0376c..14d1f8f69 100644
--- a/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb
+++ b/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb
@@ -40,6 +40,12 @@ def time_zone_query_pre
end
def utf8_query_pre
- ['SET NAMES utf8']
+ ["SET NAMES #{settings['mysql_encoding']}"]
+ end
+
+ private
+
+ def settings
+ ThinkingSphinx::Configuration.instance.settings
end
end
diff --git a/lib/thinking_sphinx/active_record/depolymorph/overridden_reflection.rb b/lib/thinking_sphinx/active_record/depolymorph/overridden_reflection.rb
index 3f58a2b29..0b40f1637 100644
--- a/lib/thinking_sphinx/active_record/depolymorph/overridden_reflection.rb
+++ b/lib/thinking_sphinx/active_record/depolymorph/overridden_reflection.rb
@@ -5,7 +5,7 @@
class ThinkingSphinx::ActiveRecord::Depolymorph::OverriddenReflection <
ThinkingSphinx::ActiveRecord::Depolymorph::BaseReflection
- module JoinConstraint
+ module BuildJoinConstraint
def build_join_constraint(table, foreign_table)
super.and(
foreign_table[options[:foreign_type]].eq(
@@ -15,6 +15,16 @@ def build_join_constraint(table, foreign_table)
end
end
+ module JoinScope
+ def join_scope(table, foreign_table, foreign_klass)
+ super.where(
+ foreign_table[options[:foreign_type]].eq(
+ options[:class_name].constantize.base_class.name
+ )
+ )
+ end
+ end
+
def self.overridden_classes
@overridden_classes ||= {}
end
@@ -28,8 +38,13 @@ def call
def klass
self.class.overridden_classes[reflection.class] ||= begin
subclass = Class.new reflection.class
- subclass.include JoinConstraint
+ subclass.include extension(reflection)
subclass
end
end
+
+ def extension(reflection)
+ reflection.respond_to?(:build_join_constraint) ?
+ BuildJoinConstraint : JoinScope
+ end
end
diff --git a/lib/thinking_sphinx/active_record/property_query.rb b/lib/thinking_sphinx/active_record/property_query.rb
index 5008bf9ad..677677545 100644
--- a/lib/thinking_sphinx/active_record/property_query.rb
+++ b/lib/thinking_sphinx/active_record/property_query.rb
@@ -27,6 +27,7 @@ def to_s
attr_reader :property, :source, :type
delegate :unscoped, :to => :base_association_class, :prefix => true
+ delegate :sql, :to => Arel
def base_association
reflections.first
@@ -135,7 +136,7 @@ def to_sql
relation = relation.joins(joins) if joins.present?
relation = relation.where("#{quoted_foreign_key} BETWEEN $start AND $end") if ranged?
relation = relation.where("#{quoted_foreign_key} IS NOT NULL")
- relation = relation.order("#{quoted_foreign_key} ASC") if type.nil?
+ relation = relation.order(sql("#{quoted_foreign_key} ASC")) if type.nil?
relation.to_sql
end
diff --git a/lib/thinking_sphinx/active_record/source_joins.rb b/lib/thinking_sphinx/active_record/source_joins.rb
index c8d5fd260..60f9f8ce5 100644
--- a/lib/thinking_sphinx/active_record/source_joins.rb
+++ b/lib/thinking_sphinx/active_record/source_joins.rb
@@ -27,7 +27,7 @@ def append_property_associations
end
def append_column_associations(column)
- return if column.__stack.empty?
+ return if column.__stack.empty? or column_included_in_queries?(column)
joins.add_join_to column.__stack if column_exists?(column)
end
@@ -54,4 +54,15 @@ def joins
joins
end
end
+
+ def source_query_properties
+ source.properties.select { |field| field.source_type == :query }
+ end
+
+ # Use "first" here instead of a more intuitive flatten because flatten
+ # will also ask each column to become an Array and that will start
+ # to retrieve data.
+ def column_included_in_queries?(column)
+ source_query_properties.collect(&:columns).collect(&:first).include?(column)
+ end
end
diff --git a/lib/thinking_sphinx/middlewares/glazier.rb b/lib/thinking_sphinx/middlewares/glazier.rb
index e691d5102..4363811bc 100644
--- a/lib/thinking_sphinx/middlewares/glazier.rb
+++ b/lib/thinking_sphinx/middlewares/glazier.rb
@@ -16,6 +16,7 @@ def call(contexts)
class Inner
def initialize(context)
@context = context
+ @indices = {}
end
def call
@@ -31,10 +32,20 @@ def call
attr_reader :context
+ def indices_for(model)
+ @indices[model] ||= context[:indices].select do |index|
+ index.model == model
+ end
+ end
+
def row_for(result)
+ ids = indices_for(result.class).collect do |index|
+ result.send index.primary_key
+ end
+
context[:raw].detect { |row|
row['sphinx_internal_class'] == result.class.name &&
- row['sphinx_internal_id'] == result.id
+ ids.include?(row['sphinx_internal_id'])
}
end
end
diff --git a/lib/thinking_sphinx/middlewares/sphinxql.rb b/lib/thinking_sphinx/middlewares/sphinxql.rb
index d4a41cbd4..1c65505c5 100644
--- a/lib/thinking_sphinx/middlewares/sphinxql.rb
+++ b/lib/thinking_sphinx/middlewares/sphinxql.rb
@@ -82,19 +82,6 @@ def descendants_from_tables
end.flatten
end
- def indices_match_classes?
- indices.collect(&:reference).uniq.sort == classes.collect { |klass|
- ThinkingSphinx::IndexSet.reference_name(klass)
- }.sort
- end
-
- def inheritance_column_select(klass)
- <<-SQL
-SELECT DISTINCT #{klass.inheritance_column}
-FROM #{klass.table_name}
-SQL
- end
-
def exclusive_filters
@exclusive_filters ||= (options[:without] || {}).tap do |without|
without[:sphinx_internal_id] = options[:without_ids] if options[:without_ids].present?
@@ -144,6 +131,19 @@ def indices
end
end
+ def indices_match_classes?
+ indices.collect(&:reference).uniq.sort == classes.collect { |klass|
+ ThinkingSphinx::IndexSet.reference_name(klass)
+ }.sort
+ end
+
+ def inheritance_column_select(klass)
+ <<-SQL
+SELECT DISTINCT #{klass.inheritance_column}
+FROM #{klass.table_name}
+SQL
+ end
+
def order_clause
order_by = options[:order]
order_by = "#{order_by} ASC" if order_by.is_a? Symbol
diff --git a/lib/thinking_sphinx/railtie.rb b/lib/thinking_sphinx/railtie.rb
index f4a3676d6..1baa2761c 100644
--- a/lib/thinking_sphinx/railtie.rb
+++ b/lib/thinking_sphinx/railtie.rb
@@ -1,6 +1,10 @@
# frozen_string_literal: true
class ThinkingSphinx::Railtie < Rails::Railtie
+ config.to_prepare do
+ ThinkingSphinx::Configuration.reset
+ end
+
initializer 'thinking_sphinx.initialisation' do
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.send :include, ThinkingSphinx::ActiveRecord::Base
diff --git a/lib/thinking_sphinx/scopes.rb b/lib/thinking_sphinx/scopes.rb
index f85ff1b04..e71c82fcc 100644
--- a/lib/thinking_sphinx/scopes.rb
+++ b/lib/thinking_sphinx/scopes.rb
@@ -26,5 +26,9 @@ def method_missing(method, *args, &block)
query, options = sphinx_scopes[method].call(*args)
search query, (options || {})
end
+
+ def respond_to_missing?(method, include_private = false)
+ super || sphinx_scopes.keys.include?(method)
+ end
end
end
diff --git a/lib/thinking_sphinx/search.rb b/lib/thinking_sphinx/search.rb
index bebc31d6e..78499897e 100644
--- a/lib/thinking_sphinx/search.rb
+++ b/lib/thinking_sphinx/search.rb
@@ -10,10 +10,11 @@ class ThinkingSphinx::Search < Array
send class )
KNOWN_OPTIONS = (
[
- :classes, :conditions, :geo, :group_by, :ids_only, :ignore_scopes,
- :indices, :limit, :masks, :max_matches, :middleware, :offset, :order,
- :order_group_by, :page, :per_page, :populate, :retry_stale, :select,
- :skip_sti, :sql, :star, :with, :with_all, :without, :without_ids
+ :classes, :conditions, :excerpts, :geo, :group_by, :ids_only,
+ :ignore_scopes, :indices, :limit, :masks, :max_matches, :middleware,
+ :offset, :order, :order_group_by, :page, :per_page, :populate,
+ :retry_stale, :select, :skip_sti, :sql, :star, :with, :with_all, :without,
+ :without_ids
] +
ThinkingSphinx::Middlewares::SphinxQL::SELECT_OPTIONS
).uniq
diff --git a/lib/thinking_sphinx/settings.rb b/lib/thinking_sphinx/settings.rb
index b9f686a5a..50fee8e5c 100644
--- a/lib/thinking_sphinx/settings.rb
+++ b/lib/thinking_sphinx/settings.rb
@@ -17,7 +17,8 @@ class ThinkingSphinx::Settings
"log" => "log/ENVIRONMENT.searchd.log",
"query_log" => "log/ENVIRONMENT.searchd.query.log",
"binlog_path" => "tmp/binlog/ENVIRONMENT",
- "workers" => "threads"
+ "workers" => "threads",
+ "mysql_encoding" => "utf8"
}.freeze
def self.call(configuration)
diff --git a/spec/acceptance/attribute_access_spec.rb b/spec/acceptance/attribute_access_spec.rb
index 2d0fd135c..0022d5e42 100644
--- a/spec/acceptance/attribute_access_spec.rb
+++ b/spec/acceptance/attribute_access_spec.rb
@@ -23,6 +23,15 @@
expect(search.first.weight).to eq(2500)
end
+ it "provides direct access to the weight with alternative primary keys" do
+ album = Album.create! :name => 'Sing to the Moon', :artist => 'Laura Mvula'
+
+ search = Album.search 'sing', :select => "*, weight()"
+ search.context[:panes] << ThinkingSphinx::Panes::WeightPane
+
+ expect(search.first.weight).to be >= 1000
+ end
+
it "can enumerate with the weight" do
gods = Book.create! :title => 'American Gods', :year => 2001
index
diff --git a/spec/acceptance/remove_deleted_records_spec.rb b/spec/acceptance/remove_deleted_records_spec.rb
index b3a14b2e2..57eb6d2c7 100644
--- a/spec/acceptance/remove_deleted_records_spec.rb
+++ b/spec/acceptance/remove_deleted_records_spec.rb
@@ -35,6 +35,18 @@
to be_empty
end
+ it "removes records from real-time index results with alternate ids" do
+ album = Album.create! :name => 'Sing to the Moon', :artist => 'Laura Mvula'
+
+ expect(Album.search('Sing', :indices => ['album_real_core']).to_a).
+ to eq([album])
+
+ album.destroy
+
+ expect(Album.search_for_ids('Sing', :indices => ['album_real_core'])).
+ to be_empty
+ end
+
it "does not remove real-time results when callbacks are disabled" do
original = ThinkingSphinx::Configuration.instance.
settings['real_time_callbacks']
diff --git a/spec/acceptance/specifying_sql_spec.rb b/spec/acceptance/specifying_sql_spec.rb
index 3b2b40387..2d790a148 100644
--- a/spec/acceptance/specifying_sql_spec.rb
+++ b/spec/acceptance/specifying_sql_spec.rb
@@ -198,6 +198,31 @@ def id_type
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .taggings.\..tag_id. AS .tag_ids. FROM .taggings.\s? WHERE \(.taggings.\..article_id. IS NOT NULL\)$/)
end
+ it "does not include attributes sourced via separate queries" do
+ index.definition_block = Proc.new {
+ indexes title
+ has taggings.tag_id, :as => :tag_ids, :source => :query
+ }
+ index.render
+
+ # We don't want it in the SELECT, JOIN or GROUP clauses. This should catch
+ # them all.
+ expect(source.sql_query).not_to include('taggings')
+ end
+
+ it "keeps the joins in for separately queried tables if they're used elsewhere" do
+ index.definition_block = Proc.new {
+ indexes taggings.tag.name, :as => :tag_names
+ has taggings.tag.created_at, :as => :tag_dates, :source => :query
+ }
+ index.render
+
+ expect(source.sql_query).to include('taggings')
+ expect(source.sql_query).to include('tags')
+ expect(source.sql_query).to_not match(/.tags.\..created_at./)
+ expect(source.sql_query).to match(/.tags.\..name./)
+ end
+
it "generates a SQL query with joins when appropriate for MVAs" do
index.definition_block = Proc.new {
indexes title
@@ -434,6 +459,17 @@ def id_type
expect(range).to match(/^SELECT MIN\(.taggings.\..article_id.\), MAX\(.taggings.\..article_id.\) FROM .taggings.\s?$/)
end
+ it "does not include fields sourced via separate queries" do
+ index.definition_block = Proc.new {
+ indexes taggings.tag.name, :as => :tags, :source => :query
+ }
+ index.render
+
+ # We don't want it in the SELECT, JOIN or GROUP clauses. This should catch
+ # them all.
+ expect(source.sql_query).not_to include('tags')
+ end
+
it "respects custom SQL snippets as the query value" do
index.definition_block = Proc.new {
indexes 'My Custom SQL Query', :as => :tags, :source => :query
diff --git a/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb b/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb
index c7ecd6f4d..91aa896ec 100644
--- a/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb
+++ b/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb
@@ -34,7 +34,7 @@
describe '#after_destroy' do
let(:index_set) { double 'index set', :to_a => [index] }
- let(:index) { double('index', :name => 'foo_core',
+ let(:index) { double('index', :name => 'foo_core', :primary_key => :id,
:document_id_for_key => 14, :type => 'plain', :distributed? => false) }
let(:instance) { double('instance', :id => 7, :new_record? => false) }
@@ -93,7 +93,7 @@
describe '#after_rollback' do
let(:index_set) { double 'index set', :to_a => [index] }
- let(:index) { double('index', :name => 'foo_core',
+ let(:index) { double('index', :name => 'foo_core', :primary_key => :id,
:document_id_for_key => 14, :type => 'plain', :distributed? => false) }
let(:instance) { double('instance', :id => 7, :new_record? => false) }
diff --git a/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb b/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb
index 76dd40ea5..0a8885960 100644
--- a/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb
+++ b/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb
@@ -23,7 +23,7 @@ module Callbacks; end
let(:connection) { double('connection', :execute => '') }
let(:index) { double 'index', :name => 'article_core',
:sources => [source], :document_id_for_key => 3, :distributed? => false,
- :type => 'plain'}
+ :type => 'plain', :primary_key => :id}
let(:source) { double('source', :attributes => []) }
before :each do
diff --git a/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb b/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb
index 3e70b0c94..dc5bcf6f6 100644
--- a/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb
+++ b/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb
@@ -48,11 +48,23 @@
end
end
-
describe '#group_concatenate' do
it "group concatenates the clause with the given separator" do
expect(adapter.group_concatenate('foo', ',')).
to eq("GROUP_CONCAT(DISTINCT foo SEPARATOR ',')")
end
end
+
+ describe '#utf8_query_pre' do
+ it "defaults to using utf8" do
+ expect(adapter.utf8_query_pre).to eq(["SET NAMES utf8"])
+ end
+
+ it "allows custom values" do
+ ThinkingSphinx::Configuration.instance.settings['mysql_encoding'] =
+ 'utf8mb4'
+
+ expect(adapter.utf8_query_pre).to eq(["SET NAMES utf8mb4"])
+ end
+ end
end
diff --git a/spec/thinking_sphinx/active_record/filter_reflection_spec.rb b/spec/thinking_sphinx/active_record/filter_reflection_spec.rb
index 387feea00..600edf7f9 100644
--- a/spec/thinking_sphinx/active_record/filter_reflection_spec.rb
+++ b/spec/thinking_sphinx/active_record/filter_reflection_spec.rb
@@ -6,7 +6,8 @@
describe '.call' do
let(:reflection) { double('Reflection', :macro => :has_some,
:options => options, :active_record => double, :name => 'baz',
- :foreign_type => :foo_type, :class => original_klass) }
+ :foreign_type => :foo_type, :class => original_klass,
+ :build_join_constraint => nil) }
let(:options) { {:polymorphic => true} }
let(:filtered_reflection) { double 'filtered reflection' }
let(:original_klass) { double }
@@ -179,13 +180,24 @@ def expected_reflection_arguments
end
it "includes custom behaviour in the subclass" do
- expect(subclass).to receive(:include).with(ThinkingSphinx::ActiveRecord::Depolymorph::OverriddenReflection::JoinConstraint)
+ expect(subclass).to receive(:include).with(ThinkingSphinx::ActiveRecord::Depolymorph::OverriddenReflection::BuildJoinConstraint)
ThinkingSphinx::ActiveRecord::FilterReflection.call(
reflection, 'foo_bar', 'Bar'
)
end if ActiveRecord::VERSION::STRING.to_f > 5.1
+ it "includes custom behaviour in the subclass" do
+ allow(reflection).to receive(:respond_to?).with(:build_join_constraint).
+ and_return(false)
+
+ expect(subclass).to receive(:include).with(ThinkingSphinx::ActiveRecord::Depolymorph::OverriddenReflection::JoinScope)
+
+ ThinkingSphinx::ActiveRecord::FilterReflection.call(
+ reflection, 'foo_bar', 'Bar'
+ )
+ end if ActiveRecord::VERSION::STRING.to_f >= 6.0
+
it "returns the new reflection" do
expect(ThinkingSphinx::ActiveRecord::FilterReflection.call(
reflection, 'foo_bar', 'Bar'
diff --git a/spec/thinking_sphinx/middlewares/glazier_spec.rb b/spec/thinking_sphinx/middlewares/glazier_spec.rb
index da731d331..f7c31a551 100644
--- a/spec/thinking_sphinx/middlewares/glazier_spec.rb
+++ b/spec/thinking_sphinx/middlewares/glazier_spec.rb
@@ -12,11 +12,12 @@ module Middlewares; end
let(:middleware) { ThinkingSphinx::Middlewares::Glazier.new app }
let(:context) { {:results => [result], :indices => [index],
:meta => {}, :raw => [raw_result], :panes => []} }
- let(:result) { double('result', :id => 10,
- :class => double(:name => 'Article')) }
- let(:index) { double('index', :name => 'foo_core') }
- let(:search) { double('search', :options => {}) }
- let(:glazed_result) { double('glazed result') }
+ let(:result) { double 'result', :id => 10, :class => model }
+ let(:model) { double 'model', :name => 'Article' }
+ let(:index) { double 'index', :name => 'foo_core', :model => model,
+ :primary_key => :id }
+ let(:search) { double 'search', :options => {} }
+ let(:glazed_result) { double 'glazed result' }
let(:raw_result) {
{'sphinx_internal_class' => 'Article', 'sphinx_internal_id' => 10} }
diff --git a/spec/thinking_sphinx/scopes_spec.rb b/spec/thinking_sphinx/scopes_spec.rb
index cfe485c49..a2bd8ec62 100644
--- a/spec/thinking_sphinx/scopes_spec.rb
+++ b/spec/thinking_sphinx/scopes_spec.rb
@@ -18,6 +18,10 @@ def self.search(query = nil, options = {})
model.sphinx_scopes[:foo] = Proc.new { {:with => {:foo => :bar}} }
end
+ it "implements respond_to" do
+ expect(model).to respond_to(:foo)
+ end
+
it "creates new search" do
expect(model.foo.class).to eq(ThinkingSphinx::Search)
end
diff --git a/thinking-sphinx.gemspec b/thinking-sphinx.gemspec
index e4494071f..378c35d20 100644
--- a/thinking-sphinx.gemspec
+++ b/thinking-sphinx.gemspec
@@ -5,7 +5,7 @@ $:.push File.expand_path('../lib', __FILE__)
Gem::Specification.new do |s|
s.name = 'thinking-sphinx'
- s.version = '4.1.0'
+ s.version = '4.2.0'
s.platform = Gem::Platform::RUBY
s.authors = ["Pat Allan"]
s.email = ["pat@freelancing-gods.com"]
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'riddle', '~> 2.3'
s.add_development_dependency 'appraisal', '~> 1.0.2'
- s.add_development_dependency 'combustion', '~> 0.8.0'
+ s.add_development_dependency 'combustion', '~> 1.1'
s.add_development_dependency 'database_cleaner', '~> 1.6.0'
s.add_development_dependency 'rspec', '~> 3.7.0'
s.add_development_dependency 'rspec-retry', '~> 0.5.6'