inertia_rails 3.0.0 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +76 -2
- data/inertia_rails.gemspec +1 -1
- data/lib/generators/inertia_rails/install/react/inertia.jsx +1 -5
- data/lib/generators/inertia_rails/install/svelte/inertia.js +1 -6
- data/lib/generators/inertia_rails/install/vue/inertia.js +0 -4
- data/lib/inertia_rails/controller.rb +4 -0
- data/lib/inertia_rails/inertia_rails.rb +8 -1
- data/lib/inertia_rails/middleware.rb +5 -0
- data/lib/inertia_rails/renderer.rb +12 -7
- data/lib/inertia_rails/rspec.rb +2 -2
- data/lib/inertia_rails/version.rb +1 -1
- data/lib/inertia_rails.rb +1 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 782c220b920be30740f826d2dbf34f61de80219947bda32a6e01b94991be2952
|
4
|
+
data.tar.gz: fd5e8f3dbf11347a14074132fbf8035f03b87bb23981ce4de80f88ba4c5bdbf6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05eacfc4a2cd7b84e49759765285ba33925851709d7ce4f7fc1322346b7c98b9978e63c9cf43f9e8eb1147272ef8a718c6c3d7919caafe94cf56ba4521f46bbb
|
7
|
+
data.tar.gz: ed94a885cfa3acb5133b81b30037c2e5f1a9fdc01ad4ebc6ac2457dfd1f5802bda2cef190825e184b5056b10794deae6da175c76fd44c69e21dd3d8134d36418
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [3.1.1] - 2023-08-21
|
8
|
+
|
9
|
+
* Fix broken partial reloads caused by comparing a list of symbolized keys with string keys from HashWithIndifferentAccess
|
10
|
+
|
11
|
+
## [3.1.0] - 2023-08-21
|
12
|
+
|
13
|
+
### Features
|
14
|
+
|
15
|
+
* CSRF protection works without additional configuration now.
|
16
|
+
* Optional deep merging of shared props.
|
17
|
+
|
18
|
+
### Fixes
|
19
|
+
|
20
|
+
* Document Inertia headers. @buhrmi
|
21
|
+
* Documentation typo fix. @lujanfernaud
|
22
|
+
* Changelog URI fix. @PedroAugustoRamalhoDuarte
|
23
|
+
|
7
24
|
## [3.0.0] - 2022-09-22
|
8
25
|
|
9
26
|
* Allow rails layout to set inertia layout. Thanks @ElMassimo!
|
data/README.md
CHANGED
@@ -79,7 +79,7 @@ end
|
|
79
79
|
|
80
80
|
### Shared Data
|
81
81
|
|
82
|
-
If you have data that you want to be provided as a prop to every component (a common use-case is
|
82
|
+
If you have data that you want to be provided as a prop to every component (a common use-case is information about the authenticated user) you can use the `shared_data` controller method.
|
83
83
|
|
84
84
|
```ruby
|
85
85
|
class EventsController < ApplicationController
|
@@ -101,6 +101,76 @@ class EventsController < ApplicationController
|
|
101
101
|
end
|
102
102
|
```
|
103
103
|
|
104
|
+
#### Deep Merging Shared Data
|
105
|
+
|
106
|
+
By default, Inertia will shallow merge data defined in an action with the shared data. You might want a deep merge. Imagine using shared data to represent defaults you'll override sometimes.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class ApplicationController
|
110
|
+
inertia_share do
|
111
|
+
{ basketball_data: { points: 50, rebounds: 100 } }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
Let's say we want a particular action to change only part of that data structure. The renderer accepts a `deep_merge` option:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
class CrazyScorersController < ApplicationController
|
120
|
+
def index
|
121
|
+
render inertia: 'CrazyScorersComponent',
|
122
|
+
props: { basketball_data: { points: 100 } },
|
123
|
+
deep_merge: true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# The renderer will send this to the frontend:
|
128
|
+
{
|
129
|
+
basketball_data: {
|
130
|
+
points: 100,
|
131
|
+
rebounds: 100,
|
132
|
+
}
|
133
|
+
}
|
134
|
+
```
|
135
|
+
|
136
|
+
Deep merging can be set as the project wide default via the InertiaRails configuration:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
# config/initializers/some_initializer.rb
|
140
|
+
InertiaRails.configure do |config|
|
141
|
+
config.deep_merge_shared_data = true
|
142
|
+
end
|
143
|
+
|
144
|
+
```
|
145
|
+
|
146
|
+
If deep merging is enabled by default, it's possible to opt out within the action:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
class CrazyScorersController < ApplicationController
|
150
|
+
inertia_share do
|
151
|
+
{
|
152
|
+
basketball_data: {
|
153
|
+
points: 50,
|
154
|
+
rebounds: 10,
|
155
|
+
}
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
def index
|
160
|
+
render inertia: 'CrazyScorersComponent',
|
161
|
+
props: { basketball_data: { points: 100 } },
|
162
|
+
deep_merge: false
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Even if deep merging is set by default, since the renderer has `deep_merge: false`, it will send a shallow merge to the frontend:
|
167
|
+
{
|
168
|
+
basketball_data: {
|
169
|
+
points: 100,
|
170
|
+
}
|
171
|
+
}
|
172
|
+
```
|
173
|
+
|
104
174
|
### Lazy Props
|
105
175
|
|
106
176
|
On the front end, Inertia supports the concept of "partial reloads" where only the props requested are returned by the server. Sometimes, you may want to use this flow to avoid processing a particularly slow prop on the intial load. In this case, you can use Lazy props. Lazy props aren't evaluated unless they're specifically requested by name in a partial reload.
|
@@ -119,7 +189,9 @@ inertia 'about' => 'AboutComponent'
|
|
119
189
|
|
120
190
|
### SSR
|
121
191
|
|
122
|
-
Enable SSR via the config settings for `ssr_enabled` and `ssr_url
|
192
|
+
Enable SSR via the config settings for `ssr_enabled` and `ssr_url`.
|
193
|
+
|
194
|
+
When using SSR, don't forget to add `<%= inertia_headers %>` to the `<head>` of your `application.html.erb`.
|
123
195
|
|
124
196
|
## Configuration
|
125
197
|
|
@@ -137,6 +209,8 @@ InertiaRails.configure do |config|
|
|
137
209
|
# ssr specific options
|
138
210
|
config.ssr_enabled = false
|
139
211
|
config.ssr_url = 'http://localhost:13714'
|
212
|
+
|
213
|
+
config.deep_merge_shared_data = false
|
140
214
|
|
141
215
|
end
|
142
216
|
```
|
data/inertia_rails.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
|
15
15
|
spec.metadata["homepage_uri"] = spec.homepage
|
16
16
|
spec.metadata["source_code_uri"] = spec.homepage
|
17
|
-
spec.metadata["changelog_uri"] = "#{spec.homepage}/CHANGELOG.md"
|
17
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
|
18
18
|
|
19
19
|
# Specify which files should be added to the gem when it is released.
|
20
20
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -1,16 +1,12 @@
|
|
1
1
|
import { App } from '@inertiajs/inertia-react';
|
2
2
|
import React from 'react';
|
3
3
|
import { render } from 'react-dom';
|
4
|
-
import axios from 'axios';
|
5
4
|
import { InertiaProgress } from '@inertiajs/progress';
|
6
5
|
|
7
6
|
document.addEventListener('DOMContentLoaded', () => {
|
8
7
|
InertiaProgress.init();
|
9
8
|
const el = document.getElementById('app')
|
10
9
|
|
11
|
-
const csrfToken = document.querySelector('meta[name=csrf-token]').content;
|
12
|
-
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken;
|
13
|
-
|
14
10
|
render(
|
15
11
|
<App
|
16
12
|
initialPage={JSON.parse(el.dataset.page)}
|
@@ -18,4 +14,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
18
14
|
/>,
|
19
15
|
el
|
20
16
|
)
|
21
|
-
});
|
17
|
+
});
|
@@ -1,12 +1,7 @@
|
|
1
|
-
import axios from 'axios'
|
2
|
-
|
3
1
|
import { createInertiaApp } from '@inertiajs/inertia-svelte'
|
4
2
|
import { InertiaProgress } from '@inertiajs/progress'
|
5
3
|
|
6
4
|
document.addEventListener('DOMContentLoaded', () => {
|
7
|
-
const csrfToken = document.querySelector('meta[name=csrf-token]').content
|
8
|
-
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken
|
9
|
-
|
10
5
|
InertiaProgress.init()
|
11
6
|
|
12
7
|
createInertiaApp({
|
@@ -16,4 +11,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
16
11
|
new App({ target: el, props })
|
17
12
|
},
|
18
13
|
})
|
19
|
-
})
|
14
|
+
})
|
@@ -1,13 +1,9 @@
|
|
1
|
-
import axios from 'axios'
|
2
1
|
import Vue from 'vue'
|
3
2
|
|
4
3
|
import { app, plugin } from '@inertiajs/inertia-vue'
|
5
4
|
import { InertiaProgress } from '@inertiajs/progress'
|
6
5
|
|
7
6
|
document.addEventListener('DOMContentLoaded', () => {
|
8
|
-
const csrfToken = document.querySelector('meta[name=csrf-token]').content
|
9
|
-
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken
|
10
|
-
|
11
7
|
InertiaProgress.init();
|
12
8
|
const el = document.getElementById('app')
|
13
9
|
|
@@ -11,6 +11,10 @@ module InertiaRails
|
|
11
11
|
InertiaRails.share(errors: session[:inertia_errors]) if session[:inertia_errors].present?
|
12
12
|
end
|
13
13
|
helper ::InertiaRails::Helper
|
14
|
+
|
15
|
+
after_action do
|
16
|
+
cookies['XSRF-TOKEN'] = form_authenticity_token unless request.inertia? || !protect_against_forgery?
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
module ClassMethods
|
@@ -13,7 +13,9 @@ module InertiaRails
|
|
13
13
|
|
14
14
|
# "Getters"
|
15
15
|
def self.shared_data(controller)
|
16
|
-
shared_plain_data.
|
16
|
+
shared_plain_data.
|
17
|
+
merge!(evaluated_blocks(controller, shared_blocks)).
|
18
|
+
with_indifferent_access
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.version
|
@@ -40,6 +42,10 @@ module InertiaRails
|
|
40
42
|
self.threadsafe_html_headers || []
|
41
43
|
end
|
42
44
|
|
45
|
+
def self.deep_merge_shared_data?
|
46
|
+
Configuration.deep_merge_shared_data
|
47
|
+
end
|
48
|
+
|
43
49
|
# "Setters"
|
44
50
|
def self.share(**args)
|
45
51
|
self.shared_plain_data = self.shared_plain_data.merge(args)
|
@@ -71,6 +77,7 @@ module InertiaRails
|
|
71
77
|
mattr_accessor(:ssr_enabled) { false }
|
72
78
|
mattr_accessor(:ssr_url) { 'http://localhost:13714' }
|
73
79
|
mattr_accessor(:default_render) { false }
|
80
|
+
mattr_accessor(:deep_merge_shared_data) { false }
|
74
81
|
|
75
82
|
def self.evaluated_version
|
76
83
|
self.version.respond_to?(:call) ? self.version.call : self.version
|
@@ -18,6 +18,7 @@ module InertiaRails
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def response
|
21
|
+
copy_xsrf_to_csrf!
|
21
22
|
status, headers, body = @app.call(@env)
|
22
23
|
request = ActionDispatch::Request.new(@env)
|
23
24
|
|
@@ -89,6 +90,10 @@ module InertiaRails
|
|
89
90
|
request.flash.keep
|
90
91
|
Rack::Response.new('', 409, {'X-Inertia-Location' => request.original_url}).finish
|
91
92
|
end
|
93
|
+
|
94
|
+
def copy_xsrf_to_csrf!
|
95
|
+
@env['HTTP_X_CSRF_TOKEN'] = @env['HTTP_X_XSRF_TOKEN'] if @env['HTTP_X_XSRF_TOKEN'] && inertia_request?
|
96
|
+
end
|
92
97
|
end
|
93
98
|
end
|
94
99
|
end
|
@@ -6,14 +6,15 @@ module InertiaRails
|
|
6
6
|
class Renderer
|
7
7
|
attr_reader :component, :view_data
|
8
8
|
|
9
|
-
def initialize(component, controller, request, response, render_method, props
|
9
|
+
def initialize(component, controller, request, response, render_method, props: nil, view_data: nil, deep_merge: nil)
|
10
10
|
@component = component.is_a?(TrueClass) ? "#{controller.controller_path}/#{controller.action_name}" : component
|
11
11
|
@controller = controller
|
12
12
|
@request = request
|
13
13
|
@response = response
|
14
14
|
@render_method = render_method
|
15
|
-
@props = props
|
15
|
+
@props = props ? props.with_indifferent_access : controller.inertia_view_assigns.with_indifferent_access
|
16
16
|
@view_data = view_data || {}
|
17
|
+
@deep_merge = !deep_merge.nil? ? deep_merge : InertiaRails.deep_merge_shared_data?
|
17
18
|
end
|
18
19
|
|
19
20
|
def render
|
@@ -41,22 +42,22 @@ module InertiaRails
|
|
41
42
|
@controller.send(:inertia_layout)
|
42
43
|
end
|
43
44
|
|
44
|
-
def
|
45
|
-
_props = ::InertiaRails.shared_data(@controller).
|
45
|
+
def computed_props
|
46
|
+
_props = ::InertiaRails.shared_data(@controller).send(prop_merge_method, @props).select do |key, prop|
|
46
47
|
if rendering_partial_component?
|
47
|
-
key.in? partial_keys
|
48
|
+
key.to_sym.in? partial_keys
|
48
49
|
else
|
49
50
|
!prop.is_a?(InertiaRails::Lazy)
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
deep_transform_values(_props, lambda {|prop| prop.respond_to?(:call) ? @controller.instance_exec(&prop) : prop })
|
54
|
+
deep_transform_values(_props, lambda {|prop| prop.respond_to?(:call) ? @controller.instance_exec(&prop) : prop }).with_indifferent_access
|
54
55
|
end
|
55
56
|
|
56
57
|
def page
|
57
58
|
{
|
58
59
|
component: component,
|
59
|
-
props:
|
60
|
+
props: computed_props,
|
60
61
|
url: @request.original_fullpath,
|
61
62
|
version: ::InertiaRails.version,
|
62
63
|
}
|
@@ -75,5 +76,9 @@ module InertiaRails
|
|
75
76
|
def rendering_partial_component?
|
76
77
|
@request.inertia_partial? && @request.headers['X-Inertia-Partial-Component'] == component
|
77
78
|
end
|
79
|
+
|
80
|
+
def prop_merge_method
|
81
|
+
@deep_merge ? :deep_merge : :merge
|
82
|
+
end
|
78
83
|
end
|
79
84
|
end
|
data/lib/inertia_rails/rspec.rb
CHANGED
@@ -74,7 +74,7 @@ end
|
|
74
74
|
|
75
75
|
RSpec::Matchers.define :have_exact_props do |expected_props|
|
76
76
|
match do |inertia|
|
77
|
-
expect(inertia.props).to eq expected_props
|
77
|
+
expect(inertia.props).to eq expected_props.with_indifferent_access
|
78
78
|
end
|
79
79
|
|
80
80
|
failure_message do |inertia|
|
@@ -84,7 +84,7 @@ end
|
|
84
84
|
|
85
85
|
RSpec::Matchers.define :include_props do |expected_props|
|
86
86
|
match do |inertia|
|
87
|
-
|
87
|
+
expect(inertia.props).to include expected_props.with_indifferent_access
|
88
88
|
end
|
89
89
|
|
90
90
|
failure_message do |inertia|
|
data/lib/inertia_rails.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inertia_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Knoles
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-08-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -198,7 +198,7 @@ licenses:
|
|
198
198
|
metadata:
|
199
199
|
homepage_uri: https://github.com/inertiajs/inertia-rails
|
200
200
|
source_code_uri: https://github.com/inertiajs/inertia-rails
|
201
|
-
changelog_uri: https://github.com/inertiajs/inertia-rails/CHANGELOG.md
|
201
|
+
changelog_uri: https://github.com/inertiajs/inertia-rails/blob/master/CHANGELOG.md
|
202
202
|
post_install_message:
|
203
203
|
rdoc_options: []
|
204
204
|
require_paths:
|
@@ -214,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
214
|
- !ruby/object:Gem::Version
|
215
215
|
version: '0'
|
216
216
|
requirements: []
|
217
|
-
rubygems_version: 3.
|
217
|
+
rubygems_version: 3.4.10
|
218
218
|
signing_key:
|
219
219
|
specification_version: 4
|
220
220
|
summary: Inertia adapter for Rails
|