recourse 4.7.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/app/views/recourses/_table.html.erb +7 -3
- data/lib/recourse/helpers/rows.rb +30 -0
- data/lib/recourse/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2de6346d2ca14ff89cc09ff75c23b72b6cc7b7502d9dcfebcb29253a53209c8c
|
|
4
|
+
data.tar.gz: aadab8161994fb71579e46a1ab1343f929f11fdf7bec5b113768f06c16887bc8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 655ce30df22d4cccd72dd6a48e559eba1e8d14720d14f2a032de9f811a510f81f5a99dbf1be8082599371eff60c24906932b682e910099cd6bc72a6dbb12bd29
|
|
7
|
+
data.tar.gz: cb32000306a3b2f20e27f6898aed2c6d3ffb78bbf32411779f85a6e28bb4c61e80d327fddf2fbca0cf82163d9e0f198997eb0b22cea5f211fc23d2d4f7b30822
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
For more information about changelogs, check [Keep a Changelog](http://keepachangelog.com) and
|
|
6
6
|
[Vandamme](http://tech-angels.github.io/vandamme).
|
|
7
7
|
|
|
8
|
+
## 4.8.0 - 2026-09-13
|
|
9
|
+
|
|
10
|
+
* [Feature] A table is redrawn when a record its rows draw changes, so a `touch: true` kept for that alone can go
|
|
11
|
+
|
|
12
|
+
A cell naming a key draws the record it points at — a booking's row reading its
|
|
13
|
+
contact's phone — and the relation's own version, `COUNT(*)` and `MAX(updated_at)`
|
|
14
|
+
over the page, sees only the rows themselves. The table kept the number the contact
|
|
15
|
+
had when the fragment was written, until somebody wrote to the booking. The key now
|
|
16
|
+
carries the newest `updated_at` among everything `recourse_includes` names, which
|
|
17
|
+
the index eager-loads already — so it is read off the records in memory and costs no
|
|
18
|
+
query.
|
|
19
|
+
|
|
20
|
+
A host that declared `belongs_to ..., touch: true` to expire such a table can drop
|
|
21
|
+
it: a touch is an UPDATE per parent per child write, it contends on the parent row,
|
|
22
|
+
and it makes every child write look like a parent update to every `after_commit` the
|
|
23
|
+
parent has. One that says a domain fact — a parent genuinely updated by its child —
|
|
24
|
+
stays. Where a row of a host's own reads through a second key, name that in
|
|
25
|
+
`recourse_includes` as a hash, the shape `includes` already takes, and the version
|
|
26
|
+
follows it there.
|
|
27
|
+
|
|
8
28
|
## 4.7.0 - 2026-09-11
|
|
9
29
|
|
|
10
30
|
* [Feature] The toast after a create or an update names the record and links it to its page
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
<%# locals: (recourses:, pagy:) %>
|
|
2
2
|
<%# A sorted or filtered table is drawn live: two requests can ask for one relation
|
|
3
3
|
and want different headings, since only one of them clicked a heading to get it. -%>
|
|
4
|
-
<%# The key carries
|
|
5
|
-
|
|
4
|
+
<%# The key carries what the rows draw besides their own columns: `MAX(updated_at)`
|
|
5
|
+
over the relation sees only the rows themselves, so a name or a ZIP read off the
|
|
6
|
+
record a row points at would keep whatever it said when the fragment was written.
|
|
7
|
+
And the row partial's digest: a host's `_row` is resolved at render, which the
|
|
8
|
+
fragment's own template digest never follows.
|
|
6
9
|
And the column list: which columns a table shows is decided in Ruby —
|
|
7
10
|
`recourse_hidden`, timestamps, counters — that no digest covers either. And the
|
|
8
11
|
bookmarks, which are the viewer's rather than the relation's — so this is what
|
|
@@ -10,7 +13,8 @@
|
|
|
10
13
|
the fragment when a square is clicked. And the zone, for the same reason again:
|
|
11
14
|
a timestamp is drawn against the reader's own clock, so without it the first
|
|
12
15
|
person to load a table would settle what hour everybody else read. -%>
|
|
13
|
-
<% key = [recourses, row_digest, resource_columns,
|
|
16
|
+
<% key = [recourses, rows_version(recourses), row_digest, resource_columns,
|
|
17
|
+
bookmark_digest, Time.zone.name] -%>
|
|
14
18
|
<% cache_if cacheable_table?, key do %>
|
|
15
19
|
<% actions = resource_actions %>
|
|
16
20
|
<div class='table-responsive'>
|
|
@@ -17,6 +17,36 @@ module Recourse
|
|
|
17
17
|
ActionView::Digestor.digest name: row.virtual_path, format: :html, finder: lookup_context
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# What the rows draw besides their own columns. A cell naming a `*_id` reads the
|
|
21
|
+
# record it points at, and `MAX(updated_at)` over the relation only ever sees the
|
|
22
|
+
# rows themselves -- so without this a table keeps a name, a phone or a ZIP that
|
|
23
|
+
# the record it belongs to has since changed.
|
|
24
|
+
#
|
|
25
|
+
# Read off the objects rather than the database: the index eager-loads exactly
|
|
26
|
+
# these, so every one of them is already in memory and this costs no query. And
|
|
27
|
+
# written out to the microsecond, which is what `cache_key_with_version` keeps
|
|
28
|
+
# too: a key expands a time by `to_s`, and two writes inside one second would
|
|
29
|
+
# otherwise be one version.
|
|
30
|
+
def rows_version(rows)
|
|
31
|
+
drawn = reached rows, resource_model.recourse_includes
|
|
32
|
+
|
|
33
|
+
drawn.filter_map { |one| one.try :updated_at }.max&.utc&.to_fs :usec
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Every record the rows reach along `includes`, in any shape `includes` accepts:
|
|
37
|
+
# a name, a list of them, or a hash naming what to follow from there.
|
|
38
|
+
def reached(rows, names)
|
|
39
|
+
Array.wrap(names).flat_map do |name|
|
|
40
|
+
next along rows, name unless name.is_a? Hash
|
|
41
|
+
|
|
42
|
+
name.flat_map { |one, nested| followed along(rows, one), nested }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def followed(rows, nested) = rows + reached(rows, nested)
|
|
47
|
+
|
|
48
|
+
def along(rows, name) = rows.flat_map { |row| Array.wrap row.public_send(name) }
|
|
49
|
+
|
|
20
50
|
# Whether the table may be kept at all. A sorted or filtered one never is: two
|
|
21
51
|
# requests can ask for one relation and want different rows, and only one of them
|
|
22
52
|
# clicked a heading to say so.
|
data/lib/recourse/version.rb
CHANGED