Framework integration
        /
          Rails
        /
          Indexing
  
        
          
          
          
        
        Nov. 20, 2023
      
  Working with relationships
To represent relationships and hierarchical structures in your records, you can embed nested objects within your attributes. These nested objects can be arrays, hashes, or a combination of both, provided they can be converted into JSON.
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Profile < ActiveRecord::Base
  include AlgoliaSearch
  belongs_to :user
  has_many :specializations
  algoliasearch do
    attribute :user do
      # restrict the nested "user" object to its `name` + `email`
      { name: user.name, email: user.email }
    end
    attribute :public_specializations do
      # build an array of public specialization (include only `title` and `another_attr`)
      specializations.select { |s| s.public? }.map do |s|
        { title: s.title, another_attr: s.another_attr }
      end
    end
  end
end
Update changes from nested relations with ActiveRecord
To update changes with nested relations using ActiveRecord, use touch and after_touch.
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# app/models/app.rb
class App < ApplicationRecord
  include AlgoliaSearch
  belongs_to :author, class_name: :User
  after_touch :index!
  algoliasearch do
    attribute :title
    attribute :author do
      author.as_json
    end
  end
end
# app/models/user.rb
class User < ApplicationRecord
  # If your association uses belongs_to
  # - use `touch: true`
  # - do not define an `after_save` hook
  has_many :apps, foreign_key: :author_id
  after_save { apps.each(&:touch) }
end
Update changes from nested relations with Sequel
With Sequel, you can use the touch plugin to propagate the changes:
Copy
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
30
31
32
33
34
35
36
# app/models/app.rb
class App < Sequel::Model
  include AlgoliaSearch
  many_to_one :author, class: :User
  plugin :timestamps
  plugin :touch
  algoliasearch do
    attribute :title
    attribute :author do
      author.to_hash
    end
  end
end
# app/models/user.rb
class User < Sequel::Model
  one_to_many :apps, key: :author_id
  plugin :timestamps
  # Can't use the associations since it won't trigger the after_save
  plugin :touch
  # Define the associations that need to be touched here
  # Less performant, but allows for the after_save hook to trigger
  def touch_associations
    apps.map(&:touch)
  end
  def touch
    super
    touch_associations
  end
end
Did you find this page helpful?