diff --git a/elasticsearch-model/lib/elasticsearch/model.rb b/elasticsearch-model/lib/elasticsearch/model.rb index f73c9a5d9..3fa319e9f 100644 --- a/elasticsearch-model/lib/elasticsearch/model.rb +++ b/elasticsearch-model/lib/elasticsearch/model.rb @@ -149,6 +149,24 @@ def client=(client) @client = client end + # Check if inheritance is enabled + # + # @note Inheritance is disabled by default. + # + def inheritance_enabled + @inheritance_enabled ||= false + end + + # Enable inheritance of index_name and document_type + # + # @example Enable inheritance + # + # Elasticsearch::Model.inheritance_enabled = true + # + def inheritance_enabled=(inheritance_enabled) + @inheritance_enabled = inheritance_enabled + end + end extend ClassMethods diff --git a/elasticsearch-model/lib/elasticsearch/model/naming.rb b/elasticsearch-model/lib/elasticsearch/model/naming.rb index ce510d2d4..2de9f8e60 100644 --- a/elasticsearch-model/lib/elasticsearch/model/naming.rb +++ b/elasticsearch-model/lib/elasticsearch/model/naming.rb @@ -34,7 +34,7 @@ def index_name name=nil, &block if @index_name.respond_to?(:call) @index_name.call else - @index_name || self.model_name.collection.gsub(/\//, '-') + @index_name || implicit(:index_name) end end @@ -58,7 +58,7 @@ def index_name=(name) # Article.document_type "my-article" # def document_type name=nil - @document_type = name || @document_type || self.model_name.element + @document_type = name || @document_type || implicit(:document_type) end @@ -69,6 +69,30 @@ def document_type name=nil def document_type=(name) @document_type = name end + + private + + def implicit(prop) + value = nil + + if Elasticsearch::Model.inheritance_enabled + self.ancestors.each do |klass| + next if klass == self + break if value = klass.respond_to?(prop) && klass.send(prop) + end + end + + value || self.send("default_#{prop}") + end + + def default_index_name + self.model_name.collection.gsub(/\//, '-') + end + + def default_document_type + self.model_name.element + end + end module InstanceMethods diff --git a/elasticsearch-model/test/unit/naming_inheritance_test.rb b/elasticsearch-model/test/unit/naming_inheritance_test.rb new file mode 100644 index 000000000..6faf136a3 --- /dev/null +++ b/elasticsearch-model/test/unit/naming_inheritance_test.rb @@ -0,0 +1,78 @@ +require "test_helper" + +class Elasticsearch::Model::NamingInheritanceTest < Test::Unit::TestCase + def setup + Elasticsearch::Model.inheritance_enabled = true + end + + def teardown + Elasticsearch::Model.inheritance_enabled = false + end + + context "Naming module with inheritance" do + class ::TestBase + extend ActiveModel::Naming + + extend Elasticsearch::Model::Naming::ClassMethods + include Elasticsearch::Model::Naming::InstanceMethods + end + + class ::Animal < ::TestBase + extend ActiveModel::Naming + + extend Elasticsearch::Model::Naming::ClassMethods + include Elasticsearch::Model::Naming::InstanceMethods + + index_name "mammals" + document_type "mammal" + end + + class ::Dog < ::Animal + end + + module ::MyNamespace + class Dog < ::Animal + end + end + + should "return the default index_name" do + assert_equal "test_bases", TestBase.index_name + assert_equal "test_bases", TestBase.new.index_name + end + + should "return the explicit index_name" do + assert_equal "mammals", Animal.index_name + assert_equal "mammals", Animal.new.index_name + end + + should "return the ancestor index_name" do + assert_equal "mammals", Dog.index_name + assert_equal "mammals", Dog.new.index_name + end + + should "return the ancestor index_name for namespaced model" do + assert_equal "mammals", ::MyNamespace::Dog.index_name + assert_equal "mammals", ::MyNamespace::Dog.new.index_name + end + + should "return the default document_type" do + assert_equal "test_base", TestBase.document_type + assert_equal "test_base", TestBase.new.document_type + end + + should "return the explicit document_type" do + assert_equal "mammal", Animal.document_type + assert_equal "mammal", Animal.new.document_type + end + + should "return the ancestor document_type" do + assert_equal "mammal", Dog.document_type + assert_equal "mammal", Dog.new.document_type + end + + should "return the ancestor document_type for namespaced model" do + assert_equal "mammal", ::MyNamespace::Dog.document_type + assert_equal "mammal", ::MyNamespace::Dog.new.document_type + end + end +end