SearchKick – Remapping an Index

Recently someone updated a Rails Model ID datatype from int to uuid. This has caused issues with ElasticSearch in my local instance:

:exception:
- Searchkick::ImportError
- '{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse [id]", "caused_by"=>{"type"=>"number_format_exception",
"reason"=>"For input string: \"03b42e85-1f09-402c-8f51-89d61c128ffc\""}} on item
with id ''03b42e85-1f09-402c-8f51-89d61c128ffc'''
:exception_object: '{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse
[id]", "caused_by"=>{"type"=>"number_format_exception", "reason"=>"For input string:
\"03b42e85-1f09-402c-8f51-89d61c128ffc\""}} on item with id ''03b42e85-1f09-402c-8f51-89d61c128ffc'''

After some digging I around I was able to resolve this by deleting the Indexes. Rails/SearchKick rebuilt them afterwords.

You can view the available entries with a GET to elasticsearch with “*” as the path.

curl 'localhost:9200/*'

It’s easier to read if you pipe it into jq.

brew install jq
curl 'localhost:9200/*' | jq keys

From the list, identify the object that is failing, mine was organizations_development. Delete the mapping with

curl -XDELETE 'localhost:9200/organizations_development'

From there, elasticsearch will rebuild it and index your data.

Easily store hard coded values with Active Hash

Hard coded data is usually stored in the class that uses it.

#app/models/camper.rb
class Camper
  MEALS = {1: 'breakfast', 2:'lunch', 3: 'supper'}
 
end
 
Camper::MEALS

Active Hash is a library that helps Rails projects abstract this data out into an ActiveRecord like model:

#app/models/meals.rb
class Meals < ActiveHash::Base
  belongs_to :camper
 
  self.data = [
    { id: 1, name: 'breakfast'},
    { id: 2, name: 'lunch'},
    { id: 3, name: 'supper'}
  ]
end
 
#app/models/camper.rb
class Camper
  # required for ActiveRecord 3.1 or later
  extend ActiveHash::Associations::ActiveRecordExtensions
  has_many :meals
 
end
 
Camper.meals

This benefits our classes by removing data it’s not meant to represent. It helps the code architecture by not littering the application with constants. If someday we want that data to be an ActiveRecord model the code is already organized for it.

ActiveHash also works with FactoryGirl

FactoryGirl.define do
  factory :camper do
    name { 'Sally' }
    meals
  end
end