Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Extract multisearch rebuild into a Rebuilder class

  • Loading branch information...
commit c0bbb38cc66f4a85daf0f0e88be6821663ee0991 1 parent ef142bf
@nertzy nertzy authored
View
46 lib/pg_search/multisearch.rb
@@ -1,56 +1,14 @@
module PgSearch
module Multisearch
- REBUILD_SQL_TEMPLATE = <<-SQL
-INSERT INTO :documents_table (searchable_type, searchable_id, content, created_at, updated_at)
- SELECT :model_name AS searchable_type,
- :model_table.id AS searchable_id,
- (
- :content_expressions
- ) AS content,
- :current_time AS created_at,
- :current_time AS updated_at
- FROM :model_table
-SQL
+ autoload :Rebuilder, "pg_search/multisearch/rebuilder"
class << self
def rebuild(model, clean_up=true)
model.transaction do
PgSearch::Document.where(:searchable_type => model.name).delete_all if clean_up
- if model.respond_to?(:rebuild_pg_search_documents)
- model.rebuild_pg_search_documents
- else
- model.connection.execute(rebuild_sql(model))
- end
+ Rebuilder.new(model).rebuild
end
end
-
- def rebuild_sql(model)
- connection = model.connection
-
- unless model.respond_to?(:pg_search_multisearchable_options)
- raise ModelNotMultisearchable.new(model)
- end
-
- columns = Array.wrap(
- model.pg_search_multisearchable_options[:against]
- )
-
- content_expressions = columns.map { |column|
- %Q{coalesce(:model_table.#{column}::text, '')}
- }.join(" || ' ' || ")
-
- REBUILD_SQL_TEMPLATE.gsub(
- ":content_expressions", content_expressions
- ).gsub(
- ":model_name", connection.quote(model.name)
- ).gsub(
- ":model_table", model.quoted_table_name
- ).gsub(
- ":documents_table", PgSearch::Document.quoted_table_name
- ).gsub(
- ":current_time", connection.quote(connection.quoted_date(Time.now))
- )
- end
end
class ModelNotMultisearchable < StandardError
View
81 lib/pg_search/multisearch/rebuilder.rb
@@ -0,0 +1,81 @@
+module PgSearch
+ module Multisearch
+ class Rebuilder
+ REBUILD_SQL_TEMPLATE = <<-SQL
+INSERT INTO :documents_table (searchable_type, searchable_id, content, created_at, updated_at)
+ SELECT :model_name AS searchable_type,
+ :model_table.id AS searchable_id,
+ (
+ :content_expressions
+ ) AS content,
+ :current_time AS created_at,
+ :current_time AS updated_at
+ FROM :model_table
+SQL
+
+ def initialize(model)
+ unless model.respond_to?(:pg_search_multisearchable_options)
+ raise ModelNotMultisearchable.new(model)
+ end
+
+ @model = model
+ end
+
+ def rebuild
+ if @model.respond_to?(:rebuild_pg_search_documents)
+ @model.rebuild_pg_search_documents
+ else
+ @model.connection.execute(rebuild_sql)
+ end
+ end
+
+ private
+
+ def connection
+ @model.connection
+ end
+
+ def rebuild_sql
+ replacements.inject(REBUILD_SQL_TEMPLATE) do |sql, (key, replacement)|
+ sql.gsub ":#{key}", replacement
+ end
+ end
+
+ def replacements
+ {
+ :content_expressions => content_expressions,
+ :model_name => model_name,
+ :model_table => model_table,
+ :documents_table => documents_table,
+ :current_time => current_time
+ }
+ end
+
+ def content_expressions
+ columns.map { |column|
+ %Q{coalesce(:model_table.#{column}::text, '')}
+ }.join(" || ' ' || ")
+ end
+
+ def columns
+ Array.wrap(@model.pg_search_multisearchable_options[:against])
+ end
+
+ def model_name
+ connection.quote(@model.name)
+ end
+
+ def model_table
+ @model.quoted_table_name
+ end
+
+ def documents_table
+ PgSearch::Document.quoted_table_name
+ end
+
+ def current_time
+ connection.quote(connection.quoted_date(Time.now))
+ end
+ end
+ end
+end
View
52 spec/pg_search/multisearch_spec.rb
@@ -105,22 +105,21 @@ def model.rebuild_pg_search_documents
PgSearch::Document.last(2).map(&:searchable).map(&:title).should =~ new_models.map(&:title)
end
end
- end
-
- describe ".rebuild_sql" do
- let(:now) { Time.now }
- before do
- Time.stub(:now => now)
- end
+ describe "the generated SQL" do
+ let(:now) { Time.now }
- context "with one attribute" do
before do
- model.multisearchable :against => [:title]
+ Time.stub(:now => now)
end
- it "should generate the proper SQL code" do
- expected_sql = <<-SQL
+ context "with one attribute" do
+ before do
+ model.multisearchable :against => [:title]
+ end
+
+ it "should generate the proper SQL code" do
+ expected_sql = <<-SQL
INSERT INTO #{PgSearch::Document.quoted_table_name} (searchable_type, searchable_id, content, created_at, updated_at)
SELECT #{connection.quote(model.name)} AS searchable_type,
#{model.quoted_table_name}.id AS searchable_id,
@@ -132,17 +131,22 @@ def model.rebuild_pg_search_documents
FROM #{model.quoted_table_name}
SQL
- PgSearch::Multisearch.rebuild_sql(model).should == expected_sql
- end
- end
+ statements = []
+ connection.stub(:execute) { |sql| statements << sql }
- context "with multiple attributes" do
- before do
- model.multisearchable :against => [:title, :content]
+ PgSearch::Multisearch.rebuild(model)
+
+ statements.should include(expected_sql)
+ end
end
- it "should generate the proper SQL code" do
- expected_sql = <<-SQL
+ context "with multiple attributes" do
+ before do
+ model.multisearchable :against => [:title, :content]
+ end
+
+ it "should generate the proper SQL code" do
+ expected_sql = <<-SQL
INSERT INTO #{PgSearch::Document.quoted_table_name} (searchable_type, searchable_id, content, created_at, updated_at)
SELECT #{connection.quote(model.name)} AS searchable_type,
#{model.quoted_table_name}.id AS searchable_id,
@@ -152,9 +156,15 @@ def model.rebuild_pg_search_documents
#{connection.quote(connection.quoted_date(now))} AS created_at,
#{connection.quote(connection.quoted_date(now))} AS updated_at
FROM #{model.quoted_table_name}
- SQL
+SQL
+
+ statements = []
+ connection.stub(:execute) { |sql| statements << sql }
- PgSearch::Multisearch.rebuild_sql(model).should == expected_sql
+ PgSearch::Multisearch.rebuild(model)
+
+ statements.should include(expected_sql)
+ end
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.