turbo-rails 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +7 -1
- data/Gemfile.lock +1 -1
- data/README.md +4 -24
- data/app/assets/javascripts/turbo.js +1 -1
- data/app/helpers/turbo/frames_helper.rb +9 -4
- data/app/helpers/turbo/streams_helper.rb +24 -1
- data/app/javascript/turbo/cable_stream_source_element.js +1 -1
- data/app/javascript/turbo/index.js +6 -2
- data/app/models/concerns/turbo/broadcastable.rb +7 -8
- data/app/models/turbo/streams/tag_builder.rb +2 -2
- data/lib/install/turbo_with_asset_pipeline.rb +20 -0
- data/lib/install/turbo_with_webpacker.rb +24 -0
- data/lib/tasks/turbo_tasks.rake +19 -1
- data/lib/turbo/engine.rb +9 -0
- data/lib/turbo/version.rb +1 -1
- data/package.json +4 -2
- data/test/frames/frames_helper_test.rb +6 -0
- data/turbo-rails.gemspec +1 -0
- metadata +5 -4
- data/lib/install/turbo.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b0552458511ec8ad34c4b0b3978d2a9ffb88485b844f60f6bc283287e0eecdd
|
4
|
+
data.tar.gz: eccd64955e5db2682efe9b503c24feeb6cbf50c1e542d7bcef0416ded95026fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 950a8abe637775b61e610d9c99a61f22fa514704a2a3d4453a0e53854c2c4dfe4e4c65f342cd534869d9d1edd83c513590a70744632a6981df52265b20ca142e
|
7
|
+
data.tar.gz: 5d97247505d6934b2bda932a53b0ca3b19d69fe7000a269001cd50ecc9f38bba090e26f50a3d489073699a93ccc50093f218465f45b054969d10c10026052100
|
data/.github/workflows/ci.yml
CHANGED
@@ -6,10 +6,16 @@ jobs:
|
|
6
6
|
matrix:
|
7
7
|
ruby-version:
|
8
8
|
- "2.7"
|
9
|
-
-
|
9
|
+
- "3.0"
|
10
|
+
continue-on-error: [ false ]
|
11
|
+
|
12
|
+
include:
|
13
|
+
- ruby-version: head
|
14
|
+
continue-on-error: true
|
10
15
|
|
11
16
|
name: ${{ format('Tests (Ruby {0})', matrix.ruby-version) }}
|
12
17
|
runs-on: ubuntu-latest
|
18
|
+
continue-on-error: ${{ matrix.continue-on-error }}
|
13
19
|
|
14
20
|
steps:
|
15
21
|
- uses: actions/checkout@v1
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Turbo
|
2
2
|
|
3
|
-
[Turbo](https://turbo.hotwire.dev) gives you the speed of a single-page web application without having to write any JavaScript. Turbo accelerates links and form submissions without requiring you to change your server-side generated HTML. It lets you carve up a page into independent frames, which can be lazy-loaded and operate as independent components. And finally, helps you make partial page updates using just HTML and a set of CRUD-like container tags. These three techniques reduce the amount of custom JavaScript that many web applications need to write by an order of magnitude. And for the few dynamic bits that are left, you're invited to
|
3
|
+
[Turbo](https://turbo.hotwire.dev) gives you the speed of a single-page web application without having to write any JavaScript. Turbo accelerates links and form submissions without requiring you to change your server-side generated HTML. It lets you carve up a page into independent frames, which can be lazy-loaded and operate as independent components. And finally, helps you make partial page updates using just HTML and a set of CRUD-like container tags. These three techniques reduce the amount of custom JavaScript that many web applications need to write by an order of magnitude. And for the few dynamic bits that are left, you're invited to finish the job with [Stimulus](https://github.com/hotwired/stimulus).
|
4
4
|
|
5
5
|
On top of accelerating web applications, Turbo was built from the ground-up to form the foundation of hybrid native applications. Write the navigational shell of your Android or iOS app using the standard platform tooling, then seamlessly fill in features from the web, following native navigation patterns. Not every mobile screen needs to be written in Swift or Kotlin to feel native. With Turbo, you spend less time wrangling JSON, waiting on app stores to approve updates, or reimplementing features you've already created in HTML.
|
6
6
|
|
@@ -32,36 +32,16 @@ With this Rails integration, you can create these asynchronous updates directly
|
|
32
32
|
|
33
33
|
## Installation
|
34
34
|
|
35
|
-
The JavaScript for Turbo can either be run through the asset pipeline, which is included with this gem, or through the package that lives on NPM, through Webpacker.
|
35
|
+
The JavaScript for Turbo can either be run through the asset pipeline, which is included with this gem, or through the package that lives on NPM, through Webpacker.
|
36
36
|
|
37
37
|
1. Add the `turbo-rails` gem to your Gemfile: `gem 'turbo-rails'`
|
38
38
|
2. Run `./bin/bundle install`
|
39
39
|
3. Run `./bin/rails turbo:install`
|
40
40
|
|
41
|
-
|
41
|
+
Running `turbo:install` will install through NPM if Webpacker is installed in the application. Otherwise the asset pipeline version is used.
|
42
42
|
|
43
|
-
|
44
|
-
2. Run `./bin/bundle install`
|
45
|
-
3. Run `./bin/yarn add @hotwired/turbo-rails`
|
46
|
-
4. Add it to your application's JavaScript pack:
|
43
|
+
If you're using Webpack and need to use either the cable consumer or the Turbo instance, you can import [`Turbo`](https://turbo.hotwire.dev/reference/drive) and/or [`cable`](https://github.com/hotwired/turbo-rails/blob/87542edecc4008c46249e5d8ede79b3eda62a5e2/app/javascript/turbo/cable.js) (`import { Turbo, cable } from "@hotwired/turbo-rails"`), but ensure that your application actually *uses* the members it `import`s when using this style (see [turbo-rails#48](https://github.com/hotwired/turbo-rails/issues/48)).
|
47
44
|
|
48
|
-
```js
|
49
|
-
import { Turbo, cable } from "@hotwired/turbo-rails"
|
50
|
-
```
|
51
|
-
|
52
|
-
Note, if you were using Turbolinks/Rails UJS in your app previously, you should remove them:
|
53
|
-
|
54
|
-
1. Remove the `turbolinks` gem from your Gemfile.
|
55
|
-
2. Run `./bin/bundle install`
|
56
|
-
3. Run `./bin/yarn remove turbolinks @rails/ujs`
|
57
|
-
4. Remove these from your application's JavaScript pack:
|
58
|
-
|
59
|
-
```js
|
60
|
-
import Rails from "@rails/ujs"
|
61
|
-
import Turbolinks from "turbolinks"
|
62
|
-
Rails.start()
|
63
|
-
Turbolinks.start()
|
64
|
-
```
|
65
45
|
|
66
46
|
## Usage
|
67
47
|
|
@@ -2675,7 +2675,7 @@ var cable = Object.freeze({
|
|
2675
2675
|
class TurboCableStreamSourceElement extends HTMLElement {
|
2676
2676
|
async connectedCallback() {
|
2677
2677
|
connectStreamSource(this);
|
2678
|
-
this.subscription = subscribeTo(this.channel, {
|
2678
|
+
this.subscription = await subscribeTo(this.channel, {
|
2679
2679
|
received: this.dispatchMessageEvent.bind(this)
|
2680
2680
|
});
|
2681
2681
|
}
|
@@ -7,17 +7,22 @@ module Turbo::FramesHelper
|
|
7
7
|
# <%= turbo_frame_tag "tray", src: tray_path(tray) %>
|
8
8
|
# # => <turbo-frame id="tray" src="http://example.com/trays/1"></turbo-frame>
|
9
9
|
#
|
10
|
-
# <%= turbo_frame_tag
|
11
|
-
# # => <turbo-frame id="
|
10
|
+
# <%= turbo_frame_tag tray, src: tray_path(tray) %>
|
11
|
+
# # => <turbo-frame id="tray_1" src="http://example.com/trays/1"></turbo-frame>
|
12
12
|
#
|
13
|
-
# <%= turbo_frame_tag "tray",
|
14
|
-
# # => <turbo-frame id="tray"
|
13
|
+
# <%= turbo_frame_tag "tray", src: tray_path(tray), target: "_top" %>
|
14
|
+
# # => <turbo-frame id="tray" target="_top" src="http://example.com/trays/1"></turbo-frame>
|
15
|
+
#
|
16
|
+
# <%= turbo_frame_tag "tray", target: "other_tray" %>
|
17
|
+
# # => <turbo-frame id="tray" target="other_tray"></turbo-frame>
|
15
18
|
#
|
16
19
|
# <%= turbo_frame_tag "tray" do %>
|
17
20
|
# <div>My tray frame!</div>
|
18
21
|
# <% end %>
|
19
22
|
# # => <turbo-frame id="tray"><div>My tray frame!</div></turbo-frame>
|
20
23
|
def turbo_frame_tag(id, src: nil, target: nil, **attributes, &block)
|
24
|
+
id = id.respond_to?(:to_key) ? dom_id(id) : id
|
25
|
+
|
21
26
|
tag.turbo_frame(**attributes.merge(id: id, src: src, target: target).compact, &block)
|
22
27
|
end
|
23
28
|
end
|
@@ -1,6 +1,29 @@
|
|
1
1
|
module Turbo::StreamsHelper
|
2
2
|
# Returns a new <tt>Turbo::Streams::TagBuilder</tt> object that accepts stream actions and renders them them as
|
3
3
|
# the template tags needed to send across the wire. This object is automatically yielded to turbo_stream.erb templates.
|
4
|
+
#
|
5
|
+
# When responding to HTTP requests, controllers can declare `turbo_stream` format response templates in that same
|
6
|
+
# style as `html` and `json` response formats. For example, consider a `MessagesController` that responds to both
|
7
|
+
# `text/html` and `text/html; turbo-stream=*; charset=utf-8` requests along with a `.turbo_stream.erb` action template:
|
8
|
+
#
|
9
|
+
# def create
|
10
|
+
# @message = Message.create!(params.require(:message).permit(:content))
|
11
|
+
# respond_to do |format|
|
12
|
+
# format.turbo_stream
|
13
|
+
# format.html { redirect_to messages_url }
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# <%# app/views/messages/create.turbo_stream.erb %>
|
18
|
+
# <%= turbo_stream.append "messages", @message %>
|
19
|
+
#
|
20
|
+
# <%= turbo_stream.replace "new_message" do %>
|
21
|
+
# <%= render partial: "new_message", locals: { room: @room } %>
|
22
|
+
# <% end %>
|
23
|
+
#
|
24
|
+
# When a `app/views/messages/create.turbo_stream.erb` template exists, the
|
25
|
+
# `MessagesController#create` will respond to `text/html; turbo-stream`
|
26
|
+
# requests by rendering the `messages/create.turbo_stream.erb` view template and transmitting the response
|
4
27
|
def turbo_stream
|
5
28
|
Turbo::Streams::TagBuilder.new(self)
|
6
29
|
end
|
@@ -15,7 +38,7 @@ module Turbo::StreamsHelper
|
|
15
38
|
#
|
16
39
|
# The example above will process all turbo streams sent to a stream name like <tt>account:5:entries</tt>
|
17
40
|
# (when Current.account.id = 5). Updates to this stream can be sent like
|
18
|
-
# <tt>entry.broadcast_append_to entry.account, :entries,
|
41
|
+
# <tt>entry.broadcast_append_to entry.account, :entries, container: "entries"</tt>.
|
19
42
|
def turbo_stream_from(*streamables)
|
20
43
|
tag.turbo_cable_stream_source channel: "Turbo::StreamsChannel", "signed-stream-name": Turbo::StreamsChannel.signed_stream_name(streamables)
|
21
44
|
end
|
@@ -4,7 +4,7 @@ import { subscribeTo } from "./cable"
|
|
4
4
|
class TurboCableStreamSourceElement extends HTMLElement {
|
5
5
|
async connectedCallback() {
|
6
6
|
connectStreamSource(this)
|
7
|
-
this.subscription = subscribeTo(this.channel, { received: this.dispatchMessageEvent.bind(this) })
|
7
|
+
this.subscription = await subscribeTo(this.channel, { received: this.dispatchMessageEvent.bind(this) })
|
8
8
|
}
|
9
9
|
|
10
10
|
disconnectedCallback() {
|
@@ -202,15 +202,14 @@ module Turbo::Broadcastable
|
|
202
202
|
# # Template: entries/_entry.turbo_stream.erb
|
203
203
|
# <%= turbo_stream.remove entry %>
|
204
204
|
#
|
205
|
-
# <%= turbo_stream.append "entries"
|
206
|
-
# <%= render partial: "entries/entry", locals: { entry: entry }, formats: [ :html ] %>
|
207
|
-
# <% end if entry.active? %>
|
205
|
+
# <%= turbo_stream.append "entries", entry if entry.active? %>
|
208
206
|
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
207
|
+
# Sends:
|
208
|
+
#
|
209
|
+
# <turbo-stream action="remove" target="entry_5"></turbo-stream>
|
210
|
+
# <turbo-stream action="append" target="entries"><template><div id="entry_5">My Entry</div></template></turbo-stream>
|
211
|
+
#
|
212
|
+
# ...to the stream named "entry:5"
|
214
213
|
def broadcast_render_later(**rendering)
|
215
214
|
broadcast_render_later_to self, **rendering
|
216
215
|
end
|
@@ -12,8 +12,8 @@
|
|
12
12
|
# <%= turbo_stream.remove entry %>
|
13
13
|
#
|
14
14
|
# <%= turbo_stream.append "entries" do %>
|
15
|
-
# <% # format
|
16
|
-
# <%= render partial: "entries/entry", locals: { entry: entry }
|
15
|
+
# <% # format is automatically switched, such that _entry.html.erb partial is rendered, not _entry.turbo_stream.erb %>
|
16
|
+
# <%= render partial: "entries/entry", locals: { entry: entry } %>
|
17
17
|
# <%= end %>
|
18
18
|
#
|
19
19
|
# Or you can render the HTML that should be part of the update inline:
|
@@ -0,0 +1,20 @@
|
|
1
|
+
APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb")
|
2
|
+
|
3
|
+
if APPLICATION_LAYOUT_PATH.exist?
|
4
|
+
say "Yield head in application layout for cache helper"
|
5
|
+
insert_into_file APPLICATION_LAYOUT_PATH.to_s, "\n <%= yield :head %>", before: /\s*<\/head>/
|
6
|
+
|
7
|
+
say "Add Turbo include tags in application layout"
|
8
|
+
insert_into_file APPLICATION_LAYOUT_PATH.to_s, "\n <%= turbo_include_tags %>", before: /\s*<\/head>/
|
9
|
+
else
|
10
|
+
say "Default application.html.erb is missing!", :red
|
11
|
+
say " Add <%= turbo_include_tags %> and <%= yield :head %> within the <head> tag in your custom layout."
|
12
|
+
end
|
13
|
+
|
14
|
+
say "Enable redis in bundle"
|
15
|
+
uncomment_lines "Gemfile", %(gem 'redis')
|
16
|
+
|
17
|
+
say "Switch development cable to use redis"
|
18
|
+
gsub_file "config/cable.yml", /development:\n\s+adapter: async/, "development:\n adapter: redis\n url: redis://localhost:6379/1"
|
19
|
+
|
20
|
+
say "Turbo successfully installed ⚡️", :green
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Some Rails versions use commonJS(require) others use ESM(import).
|
2
|
+
TURBOLINKS_REGEX = /(import .* from "turbolinks".*\n|require\("turbolinks"\).*\n)/.freeze
|
3
|
+
|
4
|
+
abort "❌ Webpacker not found. Exiting." unless defined?(Webpacker::Engine)
|
5
|
+
|
6
|
+
say "Install Turbo"
|
7
|
+
run "yarn add @hotwired/turbo-rails"
|
8
|
+
insert_into_file "#{Webpacker.config.source_entry_path}/application.js",
|
9
|
+
"import \"@hotwired/turbo-rails\"\n", before: TURBOLINKS_REGEX
|
10
|
+
|
11
|
+
say "Remove Turbolinks"
|
12
|
+
gsub_file 'Gemfile', /gem 'turbolinks'.*/, ''
|
13
|
+
run "bin/bundle", capture: true
|
14
|
+
run "bin/yarn remove turbolinks"
|
15
|
+
gsub_file "#{Webpacker.config.source_entry_path}/application.js", TURBOLINKS_REGEX, ''
|
16
|
+
gsub_file "#{Webpacker.config.source_entry_path}/application.js", /Turbolinks.start.*\n/, ''
|
17
|
+
|
18
|
+
say "Enable redis in bundle"
|
19
|
+
uncomment_lines "Gemfile", %(gem 'redis')
|
20
|
+
|
21
|
+
say "Switch development cable to use redis"
|
22
|
+
gsub_file "config/cable.yml", /development:\n\s+adapter: async/, "development:\n adapter: redis\n url: redis://localhost:6379/1"
|
23
|
+
|
24
|
+
say "Turbo successfully installed ⚡️", :green
|
data/lib/tasks/turbo_tasks.rake
CHANGED
@@ -1,6 +1,24 @@
|
|
1
|
+
def run_install_template(path) system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/#{path}.rb", __dir__)}" end
|
2
|
+
|
1
3
|
namespace :turbo do
|
2
4
|
desc "Install Turbo into the app"
|
3
5
|
task :install do
|
4
|
-
|
6
|
+
if defined?(Webpacker::Engine)
|
7
|
+
Rake::Task["turbo:install:webpacker"].invoke
|
8
|
+
else
|
9
|
+
Rake::Task["turbo:install:asset_pipeline"].invoke
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
namespace :install do
|
14
|
+
desc "Install Turbo into the app with asset pipeline"
|
15
|
+
task :asset_pipeline do
|
16
|
+
run_install_template "turbo_with_asset_pipeline"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Install Turbo into the app with webpacker"
|
20
|
+
task :webpacker do
|
21
|
+
run_install_template "turbo_with_webpacker"
|
22
|
+
end
|
5
23
|
end
|
6
24
|
end
|
data/lib/turbo/engine.rb
CHANGED
@@ -6,6 +6,15 @@ module Turbo
|
|
6
6
|
isolate_namespace Turbo
|
7
7
|
config.eager_load_namespaces << Turbo
|
8
8
|
config.turbo = ActiveSupport::OrderedOptions.new
|
9
|
+
config.autoload_once_paths = %W(
|
10
|
+
#{root}/app/channels
|
11
|
+
#{root}/app/controllers
|
12
|
+
#{root}/app/controllers/concerns
|
13
|
+
#{root}/app/helpers
|
14
|
+
#{root}/app/models
|
15
|
+
#{root}/app/models/concerns
|
16
|
+
#{root}/app/jobs
|
17
|
+
)
|
9
18
|
|
10
19
|
initializer "turbo.assets" do
|
11
20
|
if Rails.application.config.respond_to?(:assets)
|
data/lib/turbo/version.rb
CHANGED
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hotwired/turbo-rails",
|
3
|
-
"version": "7.0.0-beta.
|
3
|
+
"version": "7.0.0-beta.2",
|
4
4
|
"description": "The speed of a single-page web application without having to write any JavaScript",
|
5
5
|
"module": "app/javascript/turbo/index.js",
|
6
6
|
"main": "app/assets/javascripts/turbo.js",
|
@@ -8,7 +8,9 @@
|
|
8
8
|
"app/javascript/turbo"
|
9
9
|
],
|
10
10
|
"scripts": {
|
11
|
-
"build": "rollup -c"
|
11
|
+
"build": "rollup -c",
|
12
|
+
"prerelease": "yarn build && git --no-pager diff && echo && npm pack --dry-run && echo && read -n 1 -p \"Look OK? Press any key to publish and commit v$npm_package_version\" && echo",
|
13
|
+
"release": "npm publish && git commit -am \"$npm_package_name v$npm_package_version\" && git push"
|
12
14
|
},
|
13
15
|
"dependencies": {
|
14
16
|
"@hotwired/turbo": "^7.0.0-beta.1",
|
@@ -9,6 +9,12 @@ class Turbo::FramesHelperTest < ActionView::TestCase
|
|
9
9
|
assert_dom_equal %(<turbo-frame src="/trays/1" id="tray" target="_top"></turbo-frame>), turbo_frame_tag("tray", src: "/trays/1", target: "_top")
|
10
10
|
end
|
11
11
|
|
12
|
+
test "frame with model argument" do
|
13
|
+
record = Message.new(record_id: "1", content: "ignored")
|
14
|
+
|
15
|
+
assert_dom_equal %(<turbo-frame id="message_1"></turbo-frame>), turbo_frame_tag(record)
|
16
|
+
end
|
17
|
+
|
12
18
|
test "block style" do
|
13
19
|
assert_dom_equal(%(<turbo-frame id="tray"><p>tray!</p></turbo-frame>), turbo_frame_tag("tray") { tag.p("tray!") })
|
14
20
|
end
|
data/turbo-rails.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Stephenson
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-12-
|
13
|
+
date: 2020-12-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -60,7 +60,8 @@ files:
|
|
60
60
|
- app/models/concerns/turbo/broadcastable.rb
|
61
61
|
- app/models/turbo/streams/tag_builder.rb
|
62
62
|
- config/routes.rb
|
63
|
-
- lib/install/
|
63
|
+
- lib/install/turbo_with_asset_pipeline.rb
|
64
|
+
- lib/install/turbo_with_webpacker.rb
|
64
65
|
- lib/tasks/turbo_tasks.rake
|
65
66
|
- lib/turbo-rails.rb
|
66
67
|
- lib/turbo/engine.rb
|
@@ -161,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
161
162
|
requirements:
|
162
163
|
- - ">="
|
163
164
|
- !ruby/object:Gem::Version
|
164
|
-
version:
|
165
|
+
version: 2.6.0
|
165
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
167
|
requirements:
|
167
168
|
- - ">="
|
data/lib/install/turbo.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
say "Yield head in application layout for cache helper"
|
2
|
-
insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, "\n <%= yield :head %>", before: /\s*<\/head>/
|
3
|
-
|
4
|
-
say "Add Turbo include tags in application layout"
|
5
|
-
insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, "\n <%= turbo_include_tags %>", before: /\s*<\/head>/
|
6
|
-
|
7
|
-
say "Enable redis in bundle"
|
8
|
-
uncomment_lines "Gemfile", %(gem 'redis')
|
9
|
-
|
10
|
-
say "Switch development cable to use redis"
|
11
|
-
gsub_file "config/cable.yml", /development:\n\s+adapter: async/, "development:\n adapter: redis\n url: redis://localhost:6379/1"
|