Skip to content

Commit 103b7f6

Browse files
Copilotscarroll32
andauthored
[WIP] Sorting on globalized attributes of associations breaks when joining translations (#1614)
* Initial plan * Changes before error encountered Co-authored-by: scarroll32 <11340230+scarroll32@users.noreply.github.com> * Improve sorted translations docs --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: scarroll32 <11340230+scarroll32@users.noreply.github.com>
1 parent af55622 commit 103b7f6

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

docs/docs/getting-started/sorting.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,41 @@ class PostsController < ActionController::Base
6969
end
7070
end
7171
```
72+
73+
## Sorting on Association Attributes
74+
75+
You can sort on attributes of associated models by using the association name followed by the attribute name:
76+
77+
```ruby
78+
# Sort by the name of the associated category
79+
@q = Post.ransack(s: 'category_name asc')
80+
@posts = @q.result
81+
82+
# Sort by attributes of nested associations
83+
@q = Post.ransack(s: 'category_section_title desc')
84+
@posts = @q.result
85+
```
86+
87+
### Sorting on Globalized/Translated Attributes
88+
89+
When working with internationalized models (like those using the Globalize gem), special care is needed when sorting on translated attributes of associations. The simplest approach is to use the `sort_link` helper directly with the translation attribute:
90+
91+
```erb
92+
<!-- This works perfectly for sorting on translated attributes -->
93+
<%= sort_link @q, :translations_name %>
94+
<%= sort_link @q, :category_translations_name %>
95+
```
96+
97+
For programmatic sorting, let Ransack handle the joins first:
98+
99+
```ruby
100+
# Let Ransack establish the necessary joins for sorting
101+
@q = Book.ransack(s: 'category_translations_name asc')
102+
@books = @q.result.joins(:translations)
103+
104+
# For complex scenarios with multiple translations
105+
@q = Book.ransack(s: 'category_translations_name asc')
106+
@books = @q.result.includes(:translations, category: :translations)
107+
```
108+
109+
This ensures that Ransack properly handles the join dependencies between your main model's translations and the associated model's translations.

docs/docs/going-further/i18n.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,46 @@ en:
5151
namespace_article:
5252
title: Old Ransack Namespaced Title
5353
```
54+
55+
## Working with Globalized Attributes
56+
57+
If you're using the [Globalize gem](https://github.com/globalize/globalize) for internationalized model attributes, you may encounter issues when sorting on translated attributes of associations while also joining the main model's translations.
58+
59+
For example, if you have a `Book` model with translated `title` and a `Category` model with translated `name`, sorting on the category's translated name while joining the book's translations may not work as expected:
60+
61+
```ruby
62+
# This may not work correctly:
63+
Book.joins(:translations).ransack({ s: ['category_translations_name asc'] }).result
64+
```
65+
66+
### Workaround for Globalized Attributes Sorting
67+
68+
When working with globalized attributes and you need to sort on translated fields of associations, the simplest and most effective approach is to use the `sort_link` helper with the translation attribute directly:
69+
70+
```erb
71+
<!-- This works perfectly for sorting on translated attributes -->
72+
<%= sort_link @search, :translations_name %>
73+
<%= sort_link @search, :category_translations_name %>
74+
```
75+
76+
For programmatic sorting, let Ransack handle the joins first:
77+
78+
```ruby
79+
# Instead of joining translations first, let Ransack handle the joins:
80+
search = Book.ransack({ s: ['category_translations_name asc'] })
81+
results = search.result.joins(:translations)
82+
83+
# Or use the includes method to ensure all necessary translations are loaded:
84+
search = Book.ransack({ s: ['category_translations_name asc'] })
85+
results = search.result.includes(:translations, category: :translations)
86+
87+
# For more complex scenarios, you can manually specify the joins:
88+
search = Book.ransack({ s: ['category_translations_name asc'] })
89+
results = search.result
90+
.joins(:translations)
91+
.joins(category: :translations)
92+
```
93+
94+
The key is to let Ransack establish the necessary joins for sorting first, then add any additional joins you need for the query.
95+
96+
This approach ensures that Ransack properly handles the complex join dependencies between your main model's translations and the associated model's translations.

docs/docs/going-further/other-notes.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,39 @@ def index
116116
end
117117
```
118118

119+
### Problem with Globalized Attributes and Sorting
120+
121+
When using internationalization gems like [Globalize](https://github.com/globalize/globalize), you may encounter issues when trying to sort on translated attributes of associations while also having pre-existing joins to translation tables.
122+
123+
**Problem scenario:**
124+
```ruby
125+
# This may fail to generate proper joins:
126+
Book.joins(:translations).ransack({ s: ['category_translations_name asc'] }).result
127+
```
128+
129+
**Solution:**
130+
The simplest and most effective approach is to use the `sort_link` helper directly with the translation attribute:
131+
132+
```erb
133+
<!-- This works perfectly for sorting on translated attributes -->
134+
<%= sort_link @search, :translations_name %>
135+
<%= sort_link @search, :category_translations_name %>
136+
```
137+
138+
For programmatic sorting, let Ransack establish the sorting joins first, then add your additional joins:
139+
140+
```ruby
141+
# Let Ransack handle the sorting joins first
142+
search = Book.ransack({ s: ['category_translations_name asc'] })
143+
results = search.result.joins(:translations)
144+
145+
# Or use includes for complex scenarios
146+
search = Book.ransack({ s: ['category_translations_name asc'] })
147+
results = search.result.includes(:translations, category: :translations)
148+
```
149+
150+
This ensures that Ransack properly handles the join dependencies between your main model's translations and the associated model's translations.
151+
119152
#### `PG::UndefinedFunction: ERROR: could not identify an equality operator for type json`
120153

121154
If you get the above error while using `distinct: true` that means that

0 commit comments

Comments
 (0)