Class: MeiliSearch::Rails::IndexSettings

Inherits:
Object
  • Object
show all
Defined in:
lib/meilisearch-rails.rb

Constant Summary collapse

DEFAULT_BATCH_SIZE =
1000
DEFAULT_PRIMARY_KEY =
'id'.freeze
OPTIONS =

Meilisearch settings

%i[
  searchable_attributes
  filterable_attributes
  sortable_attributes
  displayed_attributes
  distinct_attribute
  synonyms
  stop_words
  ranking_rules
  attributes_to_highlight
  attributes_to_crop
  crop_length
  pagination
  faceting
  typo_tolerance
  proximity_precision
].freeze
CAMELIZE_OPTIONS =
%i[pagination faceting typo_tolerance].freeze

Instance Method Summary collapse

Constructor Details

#initialize(options, &block) ⇒ IndexSettings

Returns a new instance of IndexSettings.



84
85
86
87
88
# File 'lib/meilisearch-rails.rb', line 84

def initialize(options, &block)
  @options = options
  instance_exec(&block) if block_given?
  warn_searchable_missing_attributes
end

Instance Method Details

#active_record?(document) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/meilisearch-rails.rb', line 138

def active_record?(document)
  !mongoid?(document) && !sequel?(document)
end

#add_attribute(*names, &block) ⇒ Object Also known as: add_attributes

Raises:

  • (ArgumentError)


120
121
122
123
124
125
126
127
# File 'lib/meilisearch-rails.rb', line 120

def add_attribute(*names, &block)
  raise ArgumentError, 'Cannot pass multiple attribute names if block given' if block_given? && (names.length > 1)

  @additional_attributes ||= {}
  names.each do |name|
    @additional_attributes[name.to_s] = block_given? ? proc { |d| d.instance_eval(&block) } : proc { |d| d.send(name) }
  end
end

#add_index(index_uid, options = {}, &block) ⇒ Object

Raises:

  • (ArgumentError)


249
250
251
252
253
254
255
256
257
258
# File 'lib/meilisearch-rails.rb', line 249

def add_index(index_uid, options = {}, &block)
  raise ArgumentError, 'No block given' unless block_given?
  if options[:auto_index] || options[:auto_remove]
    raise ArgumentError, 'Options auto_index and auto_remove cannot be set on nested indexes'
  end

  @additional_indexes ||= {}
  options[:index_uid] = index_uid
  @additional_indexes[options] = IndexSettings.new(options, &block)
end

#additional_indexesObject



260
261
262
# File 'lib/meilisearch-rails.rb', line 260

def additional_indexes
  @additional_indexes || {}
end

#attribute(*names, &block) ⇒ Object Also known as: attributes

Raises:

  • (ArgumentError)


110
111
112
113
114
115
116
117
# File 'lib/meilisearch-rails.rb', line 110

def attribute(*names, &block)
  raise ArgumentError, 'Cannot pass multiple attribute names if block given' if block_given? && (names.length > 1)

  @attributes ||= {}
  names.flatten.each do |name|
    @attributes[name.to_s] = block_given? ? proc { |d| d.instance_eval(&block) } : proc { |d| d.send(name) }
  end
end

#attributes_to_hash(attributes, document) ⇒ Object



159
160
161
162
163
164
165
# File 'lib/meilisearch-rails.rb', line 159

def attributes_to_hash(attributes, document)
  if attributes
    attributes.to_h { |name, value| [name.to_s, value.call(document)] }
  else
    {}
  end
end

#camelize_keys(hash) ⇒ Object



225
226
227
# File 'lib/meilisearch-rails.rb', line 225

def camelize_keys(hash)
  hash.transform_keys { |key| key.to_s.camelize(:lower) }
end

#encode_attributes(value) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/meilisearch-rails.rb', line 208

def encode_attributes(value)
  case value
  when String
    value.force_encoding('utf-8')
  when Hash
    value.each { |key, val| value[key] = encode_attributes(val) }
  when Array
    value.map { |x| encode_attributes(x) }
  else
    value
  end
end

#get_attribute_names(document) ⇒ Object



155
156
157
# File 'lib/meilisearch-rails.rb', line 155

def get_attribute_names(document)
  get_attributes(document).keys
end

#get_attributes(document) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/meilisearch-rails.rb', line 167

def get_attributes(document)
  # If a serializer is set, we ignore attributes
  # everything should be done via the serializer
  if !@serializer.nil?
    attributes = @serializer.new(document).attributes
  elsif @attributes.blank?
    attributes = get_default_attributes(document)
    # no `attribute ...` have been configured, use the default attributes of the model
  elsif active_record?(document)
    # at least 1 `attribute ...` has been configured, therefore use ONLY the one configured
    document.class.unscoped do
      attributes = attributes_to_hash(@attributes, document)
    end
  else
    attributes = attributes_to_hash(@attributes, document)
  end

  attributes.merge!(attributes_to_hash(@additional_attributes, document)) if @additional_attributes

  if @options[:sanitize]
    attributes = sanitize_attributes(attributes)
  end

  attributes = encode_attributes(attributes) if @options[:force_utf8_encoding]

  attributes
end

#get_default_attributes(document) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/meilisearch-rails.rb', line 142

def get_default_attributes(document)
  if mongoid?(document)
    # work-around mongoid 2.4's unscoped method, not accepting a block
    document.attributes
  elsif sequel?(document)
    document.to_hash
  else
    document.class.unscoped do
      document.attributes
    end
  end
end

#get_setting(name) ⇒ Object



221
222
223
# File 'lib/meilisearch-rails.rb', line 221

def get_setting(name)
  instance_variable_get("@#{name}")
end

#mongoid?(document) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/meilisearch-rails.rb', line 130

def mongoid?(document)
  defined?(::Mongoid::Document) && document.class.include?(::Mongoid::Document)
end

#sanitize_attributes(value) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/meilisearch-rails.rb', line 195

def sanitize_attributes(value)
  case value
  when String
    ActionView::Base.full_sanitizer.sanitize(value)
  when Hash
    value.each { |key, val| value[key] = sanitize_attributes(val) }
  when Array
    value.map { |item| sanitize_attributes(item) }
  else
    value
  end
end

#sequel?(document) ⇒ Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/meilisearch-rails.rb', line 134

def sequel?(document)
  defined?(::Sequel::Model) && document.class < ::Sequel::Model
end

#to_settingsObject



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/meilisearch-rails.rb', line 229

def to_settings
  settings = {}
  OPTIONS.each do |k|
    v = get_setting(k)
    next if v.nil?

    settings[k] = if CAMELIZE_OPTIONS.include?(k) && v.is_a?(Hash)
                    v = camelize_keys(v)

                    # camelize keys of nested hashes
                    v.each do |key, value|
                      v[key] = camelize_keys(value) if value.is_a?(Hash)
                    end
                  else
                    v
                  end
  end
  settings
end

#use_serializer(serializer) ⇒ Object



105
106
107
108
# File 'lib/meilisearch-rails.rb', line 105

def use_serializer(serializer)
  @serializer = serializer
  # instance_variable_set("@serializer", serializer)
end

#warn_searchable_missing_attributesObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/meilisearch-rails.rb', line 90

def warn_searchable_missing_attributes
  searchables = get_setting(:searchable_attributes)&.map { |searchable| searchable.to_s.split('.').first }
  attrs = get_setting(:attributes)&.map { |k, _| k.to_s }

  if searchables.present? && attrs.present?
    (searchables - attrs).each do |missing_searchable|
      warning = <<~WARNING
        [meilisearch-rails] #{missing_searchable} declared in searchable_attributes but not in attributes. \
        Please add it to attributes if it should be searchable.
      WARNING
      MeiliSearch::Rails.logger.warn(warning)
    end
  end
end