问题
I have an ActiveAdmin app with a simple model that I want to persist in Elastic Search with Tire:
class Person
include Tire::Model::Persistence
property :firstName
property :lastName
end
But I get this error on the index action:
NoMethodError (undefined method `quoted_table_name' for Person:Class)
What have I missed?
回答1:
First of all, I skipped a few steps enabling Tire persistence. Thanks to Chris Berkhout's post on this topic my model now looks like this:
class Person
include Tire::Model::Persistence
include Tire::Model::Search
include Tire::Model::Callbacks
index_name ES_INDEX_NAME
# Refresh ES so any changes are immediately visible
refresh = lambda { Tire::Index.new(ES_INDEX_NAME).refresh }
after_save &refresh
after_destroy &refresh
property :firstName
property :lastName
property :updated_at
before_save { |n| n.updated_at = Time.now }
def self.touch_es
# Ensure a mapping in a fresh index, so that Note.all can sort on updated_at
n = Person.new
n.save
n.destroy
end
def self.all
# Override so that Note.all comes back sorted on updated_at, rather than _id
search { sort { by :updated_at, 'desc' } }
end
def self.q(q)
search { sort { by :updated_at, 'desc' }; query { string q } }
end
end
And I needed to add a es.rake task in lib/tasks to set up the index:
namespace :es do
desc "Delete the ElasticSearch index for the current environment"
task :drop => :environment do
Tire::Index.new(ES_INDEX_NAME).delete
end
desc "Create the ElasticSearch index for the current environment"
task :create => :environment do
Tire::Index.new(ES_INDEX_NAME).create
Person.touch_es
end
end
And an initializer es.rb in config/initializers to define the index name:
ES_INDEX_NAME = "#{Rails.application.class.parent_name.downcase}_#{Rails.env}"
Works a treat!
As for trying to get ActiveAdmin working with ES persistence, I see that AA is tied to ActiveRecord, though ActiveModel or an ORM-independent version is in the works.
来源:https://stackoverflow.com/questions/9119919/error-using-tire-persistence