Open
Description
Description
If you provide a custom primary key method and also specify attributes other than the real primary key of the model in the meilisearch
block, the documents in the meilisearch instance will not contain the model's real primary key and therefore cannot map to database records.
Expected behavior
MeiliSearch still includes ID in its documents and fetching does not fail.
Reproduction script
require 'bundler/inline'
gemfile do
gem "rails", "~> 7.1.3"
gem "sqlite3", "~> 1.4"
gem "meilisearch-rails", "~> 0.11.1"
end
MeiliSearch::Rails.configuration = {
meilisearch_url: ENV.fetch('MEILISEARCH_HOST', 'http://localhost:7700'),
meilisearch_api_key: ENV.fetch('MEILISEARCH_API_KEY', 'masterKey')
}
MeiliSearch::Rails.client.delete_index 'dogs'
MeiliSearch::Rails.client.delete_index 'cats'
sleep 0.1
FileUtils.rm('data.sqlite3') if File.exist?('data.sqlite3')
require 'active_record'
ActiveRecord::Base.establish_connection(
'adapter' => defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3',
'database' => 'data.sqlite3',
'pool' => 5,
'timeout' => 5000
)
ActiveRecord::Schema.define do
create_table(:dogs) { |t| t.string :name }
create_table(:cats) { |t| t.string :name }
end
# With custom primary key
class Dog < ActiveRecord::Base
include MeiliSearch::Rails
meilisearch index_uid: 'dogs', primary_key: :ms_id do
attribute :name
end
def ms_id
"dog_#{id}"
end
end
# Without custom primary key
class Cat < ActiveRecord::Base
include MeiliSearch::Rails
meilisearch index_uid: 'cats' do
attribute :name
end
end
Dog.create name: 'spikey'
Cat.create name: 'fluffy'
sleep 0.5
p Dog.search 'spikey' # Will return nothing
# []
p Dog.index.search('spikey')['hits'] # Documents without IDs
# [{"ms_id"=>"dog_2", "name"=>"spikey"}]
p Cat.search 'fluffy' # Returns a cat correctly
# [#<Cat id: 1, name: "fluffy">]
p Cat.index.search('fluffy')['hits'] # Documents still have IDs
# [{"id"=>"1", "name"=>"fluffy"}]