Integrations / Frameworks / Rails / Serializing Models
Mar. 18, 2019

Serializing Models

Customizing attributes

By default, all model attributes will be sent to Algolia. It makes getting started very easy but in most cases, you want to define what attributes are sent to improve your search.

The attribute method

The attribute method will define what model attribute to send. It can be passed one or many symbols. In this case, it will call the method with the same name. The method can also accept a block, in this case, only one symbol can be passed to define the attribute name and the block will define the value.

To keep your code as readable as possible:

  • the attributes method is an alias to attribute
  • both methods can be called multiple times

Here is an example, combining the various ways to call define attributes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    # Sending 3 model attributes
    attributes :first_name, :last_name, :email
    # Sending a dynamic attribute defined by instance method
    attribute :full_name
    # Aliasing birth_date attribute to dob with shorthand block syntax
    attribute (:dob) { birth_date }
    # Nesting the company information for organization-sake
    attribute :company do
      { name: company_name, website: company_website }
    end
  end

  def full_name
    "#{first_name} #{last_name}"
  end
end

As soon as you’re using dynamic attributes, the gem is unable to detect if the attribute has changed. This can result in many unexpected operations.
Make sure you read the “Automatic updates” section to work around it.

The add_attribute method

Alternatively, you can use the add_attribute (the plural version is also available). It works just like attribute but will be handled a little bit differently internally. The main reason to use this method is if you want to add all attributes plus some additional ones, or if you’re using a serializer (see below).

1
2
3
4
5
6
7
8
9
10
11
12
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    # Since no +attribute+ were defined, all model attributes will be sent.
    # Plus the full_name attribute
    add_attribute :full_name do
      "#{first_name} #{last_name}"
    end
  end

end

Custom objectID

The objectID attribute is essential in Algolia. It’s the primary key of your records in Algolia index, it’s needed to access your records (update or delete for instance) after it was created.

By default, this gem will use your record’s id as the objectID. You can change this behavior specifying the :id option. Please make sure this is a unique id, otherwise you’ll find records missing or being overwritten by other models.

The id option value can be a model attribute or you can define your custom attribute.

1
2
3
4
5
6
class UniqUser < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch id: :uniq_email do
  end
end
1
2
3
4
5
6
7
8
9
10
class UniqUser < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch id: :algolia_id do
  end

  def algolia_id
    "user_#{id}"
  end
end

Helpers

Algolia has some special features that require you to pass your data to a conventional attribute name. Typically, to use geo search, you must add the coordinates of the record under the _geoloc key. This gem provides helpers to ensure the convention is followed.

It’s recommended to read about the special _changed? method for following helpers.

Coordinates (geolocalisation)

Setting coordinates to your records will allow you to use any geo-search features.

1
2
3
4
5
6
7
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    geoloc :latitude, :longitude
  end
end

Tags

The _tags attributes is required to use the tagFilters feature. Filters can be used with any attributes, as long as you declare it in the settings.

1
2
3
4
5
6
7
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    tags ['trusted']
  end
end

A block can also be defined to create tags dynamically.

1
2
3
4
5
6
7
8
9
10
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    tags do
      [first_name.blank? || last_name.blank? ? 'partial' : 'full',
      has_valid_email? ? 'valid_email' : 'invalid_email']
    end
  end
end

Sanitizer

You can sanitize all your attributes using the sanitize option. It will strip all HTML tags from your attributes.

1
2
3
4
5
6
7
8
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch sanitize: true do
    attributes :name, :email, :company
  end
end

If you’re using Rails 4.2+, you need to add rails-html-sanitizer to your dependencies.

1
gem 'rails-html-sanitizer'

UTF-8 Encoding

You can force the UTF-8 encoding of all your attributes using the force_utf8_encoding option.

1
2
3
4
5
6
7
8
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch force_utf8_encoding: true do
    attributes :name, :email, :company
  end
end

This option is only compatible with Ruby 1.9+

Using ActiveModel Serializer

You can use ActiveModel Serializer to extract all the logic to create your records into a separate class.

In the algoliasearch block, you need to specify what serializer class to use.

If a serializer is set, everything defined via the attribute(s) method will be ignored, but you can still use add_attribute(s) as well as tags or geoloc helpers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# post_serializer.rb
class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :text
  has_one :author
  has_many :comments
end

# author_serializer.rb
class AuthorSerializer < ActiveModel::Serializer
  attributes :id, :name
end

# comment_serializer.rb
class CommentSerializer < ActiveModel::Serializer
  attributes :text
  has_one :author
end

# post.rb
class Post.rb
  has_one :author
  has_many :comments

  algoliasearch do
    use_serializer PostSerializer
    # Also combine the serialize result with
    # `add_attribute`, `tags` or `geoloc` if necessary
  end
end

Did you find this page helpful?