> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Serialization

> Convert Rails models to Algolia records.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

By default, all model attributes are indexed.
To control, which attributes to index, use the `attribute` method.

## The `attribute` method

The `attribute` method defines which model attributes to index.

* If you pass one or more symbols, it calls the methods with the same name.
* If you pass it a block, you can only use one symbol to define the attribute name.
  The block defines the value.

To keep your code as readable as possible:

* `attributes` is an alias for `attribute`
* You can call both methods multiple times

For example:

```ruby Ruby icon=code theme={"system"}
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
```

If you're using dynamic attributes,
you need to handle updates to those attributes manually.
For more information, see [Automatic updates](/doc/framework-integration/rails/indexing/indexing).

## The `add_attribute` method

You can use the `add_attribute` and `add_attributes` methods,
if you want to add new attributes to your <Records />.

```ruby Ruby icon=code theme={"system"}
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 object IDs

Every Algolia record needs an `objectID`.
By default, this gem uses Rails `id` as the Algolia `objectID`.

To use a custom ID, use the `id` option.
Each `objectID` must be unique in the <Index />, or your records might be overwritten or deleted by other models.

The `id` can be a model attribute or you can define your own attribute.

```ruby Ruby icon=code theme={"system"}
class UniqUser < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch(id: :uniq_email) do
  end
end
```

```ruby Ruby icon=code theme={"system"}
class UniqUser < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch(id: :algolia_id) do
  end

  def algolia_id
    "user_#{id}"
  end
end
```

## Helpers

The `algoliasearch-rails` gem comes with helpers for special Algolia attributes.
To detect changes for these helpers,
see [`tags` and `geoloc` helpers](/doc/framework-integration/rails/indexing/indexing#tags-and-geoloc-helpers).

### Coordinates for location search

Adding coordinates to your records lets you [search by location](/doc/api-reference/api-parameters/aroundLatLng).

```ruby Ruby icon=code theme={"system"}
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    geoloc :latitude, :longitude
  end
end
```

### Tags

The `_tags` attribute is required for [filtering by tags](/doc/api-reference/api-parameters/tagFilters).
You use any attribute for filtering if you [configure it in the settings](/doc/framework-integration/rails/index-configuration/index-settings).

```ruby Ruby icon=code theme={"system"}
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    tags ["trusted"]
  end
end
```

To create tags dynamically, use a block:

```ruby Ruby icon=code theme={"system"}
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
```

## Sanitize HTML

To remove all HTML tags from your attributes,
use the `sanitize` options.

```ruby Ruby icon=code theme={"system"}
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch(sanitize: true) do
    attributes :name, :email, :company
  end
end
```

## UTF-8 encoding

To make all your attributes UTF-8 encoded,
use the `force_utf8_encoding` option.

```ruby Ruby icon=code theme={"system"}
class Contact < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch(force_utf8_encoding: true) do
    attributes :name, :email, :company
  end
end
```

## Serialization with ActiveModelSerializers

You can use [ActiveModelSerializers](https://github.com/rails-api/active_model_serializers/tree/v0.10.6/docs)
to extract all logic for creating your records into a separate class.

In the `algoliasearch` block, specify what class to use with `use_serializer`.
If specified, all `attribute(s)` methods are ignored.
You can still use `add_attribute(s)` and the `tags` or `geoloc` helpers.

```ruby Ruby icon=code theme={"system"}
# 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
  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
```
