Conversation
📝 WalkthroughWalkthroughThe Ruby SDK adds methods for listing, retrieving, upserting, and deleting dynamic search rules. It normalizes nested rule conditions and actions, returns asynchronous tasks for mutations, adds RSpec coverage, and provides Ruby code samples. ChangesDynamic search rules
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant RubyClient
participant MeilisearchAPI
participant ModelsTask
RubyClient->>MeilisearchAPI: List or retrieve dynamic search rules
RubyClient->>MeilisearchAPI: Upsert or delete a dynamic search rule
MeilisearchAPI-->>RubyClient: Rule response or task response
RubyClient->>ModelsTask: Wrap asynchronous response as Models::Task
Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/meilisearch/client.rb`:
- Around line 523-536: Update dynamic_search_rule_body and
dynamic_search_rule_conditions so Utils.transform_attributes does not
recursively transform conditions.filter.values; preserve facet keys such as
product_type while continuing to transform only the structural condition fields.
Add an integration case covering an underscored facet name and verify the
generated server filter condition retains the original key.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 192dd0c2-9256-4a69-83f2-830c66c407be
📒 Files selected for processing (3)
.code-samples.meilisearch.yamllib/meilisearch/client.rbspec/meilisearch/client/dynamic_search_rules_spec.rb
| def dynamic_search_rule_body(options) | ||
| body = Utils.transform_attributes(options) | ||
| body['conditions'] = dynamic_search_rule_conditions(body['conditions']) if body['conditions'] | ||
| body['actions'] = body['actions'].map { |entry| dynamic_search_rule_action(entry) } if body['actions'] | ||
|
|
||
| body | ||
| end | ||
|
|
||
| def dynamic_search_rule_conditions(conditions) | ||
| conditions = Utils.transform_attributes(conditions) | ||
| ['query', 'time', 'filter'].each do |condition| | ||
| conditions[condition] = Utils.transform_attributes(conditions[condition]) if conditions[condition] | ||
| end | ||
| conditions |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Preserve keys in filter.values.
Utils.transform_attributes recursively transforms nested hashes. At Line 524, it transforms conditions.filter.values before this helper can isolate it. A facet named product_type can become productType, which changes the server filter condition.
Keep filter.values unchanged. Transform only the structural condition fields. Add an integration case with an underscored facet name.
Proposed fix
def dynamic_search_rule_body(options)
- body = Utils.transform_attributes(options)
- body['conditions'] = dynamic_search_rule_conditions(body['conditions']) if body['conditions']
+ body = options.dup
+ conditions = body.delete(:conditions) || body.delete('conditions')
+ body = Utils.transform_attributes(body)
+ body['conditions'] = dynamic_search_rule_conditions(conditions) if conditions
body['actions'] = body['actions'].map { |entry| dynamic_search_rule_action(entry) } if body['actions']
body
end
def dynamic_search_rule_conditions(conditions)
- conditions = Utils.transform_attributes(conditions)
- ['query', 'time', 'filter'].each do |condition|
- conditions[condition] = Utils.transform_attributes(conditions[condition]) if conditions[condition]
+ conditions = conditions.dup
+ filter = conditions.delete(:filter) || conditions.delete('filter')
+ conditions = Utils.transform_attributes(conditions)
+
+ if filter
+ filter = filter.dup
+ values = filter.delete(:values) || filter.delete('values')
+ filter = Utils.transform_attributes(filter)
+ filter['values'] = values if values
+ conditions['filter'] = filter
end
+
conditions
end📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def dynamic_search_rule_body(options) | |
| body = Utils.transform_attributes(options) | |
| body['conditions'] = dynamic_search_rule_conditions(body['conditions']) if body['conditions'] | |
| body['actions'] = body['actions'].map { |entry| dynamic_search_rule_action(entry) } if body['actions'] | |
| body | |
| end | |
| def dynamic_search_rule_conditions(conditions) | |
| conditions = Utils.transform_attributes(conditions) | |
| ['query', 'time', 'filter'].each do |condition| | |
| conditions[condition] = Utils.transform_attributes(conditions[condition]) if conditions[condition] | |
| end | |
| conditions | |
| def dynamic_search_rule_body(options) | |
| body = options.dup | |
| conditions = body.delete(:conditions) || body.delete('conditions') | |
| body = Utils.transform_attributes(body) | |
| body['conditions'] = dynamic_search_rule_conditions(conditions) if conditions | |
| body['actions'] = body['actions'].map { |entry| dynamic_search_rule_action(entry) } if body['actions'] | |
| body | |
| end | |
| def dynamic_search_rule_conditions(conditions) | |
| conditions = conditions.dup | |
| filter = conditions.delete(:filter) || conditions.delete('filter') | |
| conditions = Utils.transform_attributes(conditions) | |
| if filter | |
| filter = filter.dup | |
| values = filter.delete(:values) || filter.delete('values') | |
| filter = Utils.transform_attributes(filter) | |
| filter['values'] = values if values | |
| conditions['filter'] = filter | |
| end | |
| conditions |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/meilisearch/client.rb` around lines 523 - 536, Update
dynamic_search_rule_body and dynamic_search_rule_conditions so
Utils.transform_attributes does not recursively transform
conditions.filter.values; preserve facet keys such as product_type while
continuing to transform only the structural condition fields. Add an integration
case covering an underscored facet name and verify the generated server filter
condition retains the original key.
Why?
adds ruby client support for the dynamic search rules API introduced in meilisearch v1.50, including the filter condition and lastUpdatedAt response added in v1.51.
closes #708
closes #709
What?
Testing
one unrelated compact integration example is excluded from the broader windows run because index compaction fails on the local windows server.
AI assistance
used codex to help implement the client methods and draft the integration tests. i reviewed the diff and validated it against meilisearch enterprise v1.51.0 locally.
See Also
Changelog
Summary by CodeRabbit