ruby on rails_如何将刺激添加到Ruby on Rails应用程序

ruby on rails

介绍 (Introduction)

If you are working with a Ruby on Rails project, your requirements may include some interactivity with the HTML generated by your view templates. If so, you have a few choices for how to implement this interactivity.

如果您正在使用Ruby on Rails项目,那么您的需求可能包括与视图模板生成HTML的交互性。 如果是这样,您可以选择几种方式来实现这种交互性。

For example, you could implement a JavaScript framework like React or Ember. If your requirements include handling state on the client side, or if you are concerned about performance issues associated with frequent queries to the server, then choosing one of these frameworks may make sense. Many Single Page Applications (SPAs) take this approach.

例如,您可以实现一个JavaScript框架,例如React或Ember 。 如果您的要求包括在客户端上处理状态,或者您担心与服务器频繁查询相关的性能问题,那么选择这些框架之一可能是有意义的。 许多单页应用程序(SPA)都采用这种方法。

However, there are several considerations to keep in mind when implementing a framework that manages state and frequent updates on the client side:

但是,在实现用于管理客户端状态和频繁更新的框架时,需要牢记一些注意事项:

  1. It’s possible for loading and conversion requirements — things like parsing JavaScript, and fetching and converting JSON to HTML — to limit performance.

    可能需要满足加载和转换要求(例如解析JavaScript以及将JSON提取并将其转换为HTML)来限制性能。
  2. Commitment to a framework may involve writing more code than your particular use case requires, particularly if you are looking for small-scale JavaScript enhancements.

    对框架的承诺可能涉及编写超出特定用例要求的代码,特别是在您正在寻找小规模JavaScript增强功能的情况下。
  3. State managed on both the client and server side can lead to a duplication of efforts, and increases the surface area for errors.

    在客户端和服务器端管理的状态可能导致工作重复,并增加了错误的表面积。

As an alternative, the team at Basecamp (the same team that wrote Rails) has created Stimulus.js, which they describe as “a modest JavaScript framework for the HTML you already have.” Stimulus is meant to enhance a modern Rails application by working with server-side generated HTML. State lives in the Document Object Model (DOM), and the framework offers standard ways of interacting with elements and events in the DOM. It works side by side with Turbolinks (included in Rails 5+ by default) to improve performance and load times with code that is limited and scoped to a clearly defined purpose.

作为替代方案, Basecamp的团队(与编写Rails的团队相同)创建了Stimulus.js ,他们将其描述为“用于现有HTML的适度JavaScript框架”。 Stimulus旨在通过使用服务器端生成HTML来增强现代的Rails应用程序。 状态存在于文档对象模型(DOM)中 ,并且该框架提供了与DOM中的元素和事件进行交互的标准方式。 它与Turbolinks (默认情况下包含在Rails 5+中)并肩工作,以限制代码的范围和明确定义的目的,从而提高性能和加载时间。

In this tutorial, you will install and use Stimulus to build on an existing Rails application that offers readers information about sharks. The application already has a model for handling shark data, but you will add a nested resource for posts about individual sharks, allowing users to build out a body of thoughts and opinions about sharks. This piece runs roughly parallel to How To Create Nested Resources for a Ruby on Rails Application, except that we will be using JavaScript to manipulate the position and appearance of posts on the page. We will also take a slightly different approach to building out the post model itself.

在本教程中,您将安装并使用Stimulus在现有的Rails应用程序上构建,该应用程序为读者提供有关鲨鱼的信息。 该应用程序已经有一个用于处理鲨鱼数据的模型,但是您将为有关单个鲨鱼的帖子添加一个嵌套资源,从而允许用户建立有关鲨鱼的思想和观点。 这段代码与如何为Ruby on Rails应用程序创建嵌套资源大致平行,除了我们将使用JavaScript来操纵页面上帖子的位置和外观外。 我们还将采用略有不同的方法来构建邮政模型本身。

先决条件 (Prerequisites)

To follow this tutorial, you will need:

要遵循本教程,您将需要:

  • A local machine or development server running Ubuntu 18.04. Your development machine should have a non-root user with administrative privileges and a firewall configured with ufw. For instructions on how to set this up, see our Initial Server Setup with Ubuntu 18.04 tutorial.

    运行Ubuntu 18.04的本地计算机或开发服务器。 您的开发机器应具有具有管理特权的非root用户,以及使用ufw配置的防火墙。 有关如何进行此设置的说明,请参阅我们的《 Ubuntu 18.04初始服务器设置》教程。

  • Node.js and npm installed on your local machine or development server. This tutorial uses Node.js version 10.16.3 and npm version 6.9.0. For guidance on installing Node.js and npm on Ubuntu 18.04, follow the instructions in the “Installing Using a PPA” section of How To Install Node.js on Ubuntu 18.04.

    安装在本地计算机或开发服务器上的Node.js和npm 。 本教程使用Node.js 10.16.3版和npm 6.9.0版。 有关在Ubuntu 18.04上安装Node.js和npm的指导,请遵循如何在Ubuntu 18.04上安装Node.js的“使用PPA安装”部分中的说明。

  • Ruby, rbenv, and Rails installed on your local machine or development server, following Steps 1-4 in How To Install Ruby on Rails with rbenv on Ubuntu 18.04. This tutorial uses Ruby 2.5.1, rbenv 1.1.2, and Rails 5.2.3.

    遵循在Ubuntu 18.04上如何使用rbenv安装Ruby on Rails的 步骤1-4中的步骤 ,将Ruby, rbenv和Rails安装在本地计算机或开发服务器上 。 本教程使用Ruby 2.5.1 ,rbenv 1.1.2和Rails 5.2.3 。

  • SQLite installed, and a basic shark information application created, following the directions in How To Build a Ruby on Rails Application.

    按照如何构建Ruby on Rails应用程序中的指示安装SQLite,并创建基本的shark信息应用程序 。

第1步-创建嵌套模型 (Step 1 — Creating a Nested Model)

Our first step will be to create a nested Post model, which we will associate with our existing Shark model. We will do this by creating Active Record associations between our models: posts will belong to particular sharks, and each shark can have multiple posts.

我们的第一步将是创建一个嵌套的Post 模型 ,将其与我们现有的Shark模型关联。 我们将通过在模型之间创建Active Record 关联来做到这一点:帖子将属于特定的鲨鱼,每个鲨鱼可以有多个帖子。

To get started, navigate to the sharkapp directory that you created for your Rails project in the prerequisites:

首先,在先决条件中导航到为Rails项目创建的sharkapp目录:

  • cd sharkapp

    cd sharkapp

To create our Post model, we’ll use the rails generate command with the model generator. Type the following command to create the model:

要创建我们的Post模型,我们将在model生成器中使用rails generate命令。 键入以下命令来创建模型:

  • rails generate model Post body:text shark:references

    rails生成模型Post body:text shark:references

With body:text, we’re telling Rails to include a body field in the posts database table — the table that maps to the Post model. We’re also including the :references keyword, which sets up an association between the Shark and Post models. Specifically, this will ensure that a foreign key representing each shark entry in the sharks database is added to the posts database.

通过body:text ,我们告诉Rails在posts数据库表(映射到Post模型的表)中包含body字段。 我们还包括:references关键字,它在SharkPost模型之间建立了关联。 具体来说,这将确保将代表sharks数据库中每个鲨鱼条目的外键添加到posts数据库。

Once you have run the command, you will see output confirming the resources that Rails has generated for the application. Before moving on, you can check your database migration file to look at the relationship that now exists between your models and database tables. Use the following command to look at the contents of the file, making sure to substitute the timestamp on your own migration file for what’s shown here:

运行命令后,将看到输出确认Rails为应用程序生成的资源。 在继续之前,您可以检查数据库迁移文件以查看模型与数据库表之间现在存在的关系。 使用以下命令查看文件的内容,并确保将您自己的迁移文件上的时间戳替换为此处显示的内容:

  • cat db/migrate/20190805132506_create_posts.rb

    猫数据库/迁移/ 20190805132506 _create_posts.rb

You will see the following output:

您将看到以下输出:


   
   
     
     
     
     
Output
class CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| t.text :body t.references :shark, foreign_key: true t.timestamps end end end

As you can see, the table includes a column for a shark foreign key. This key will take the form of model_name_id — in our case, shark_id.

如您所见,该表包括一个用于显示鲨鱼外键的列。 该密钥将采用model_name _id的形式,在本例中为shark _id

Rails has established the relationship between the models elsewhere as well. Take a look at the newly generated Post model with the following command:

Rails在其他地方也建立了模型之间的关系。 使用以下命令查看新生成的Post模型:

  • cat app/models/post.rb

    猫app / models / post.rb

   
   
     
     
     
     
Output
class Post < ApplicationRecord belongs_to :shark end

The belongs_to association sets up a relationship between models in which a single instance of the declaring model belongs to a single instance of the named model. In the case of our application, this means that a single post belongs to a single shark.

belongs_to关联在模型之间建立关系,在该模型中,声明模型的单个实例属于命名模型的单个实例。 在我们的应用程序中,这意味着单个职位属于单个鲨鱼。

Though Rails has already set the belongs_to association in our Post model, we will need to specify a has_many association in our Shark model as well in order for that relationship to function properly.

尽管Rails已经在我们的Post模型中设置了belongs_to关联,但我们仍需要在Shark模型中指定has_many关联,以使该关系正常运行。

To add the has_many association to the Shark model, open app/models/shark.rb using nano or your favorite editor:

要将has_many关联添加到Shark模型, app/models/shark.rb使用nano或您喜欢的编辑器打开app/models/shark.rb

  • nano app/models/shark.rb

    纳米app / models / shark.rb

Add the following line to the file to establish the relationship between sharks and posts:

将以下行添加到文件中,以建立鲨鱼和职位之间的关系:

~/sharkapp/app/models/shark.rb
〜/ sharkapp / app / models / shark.rb
class Shark < ApplicationRecord
  has_many :posts
  validates :name, presence: true, uniqueness: true
  validates :facts, presence: true
end

One thing that is worth thinking about here is what happens to posts once a particular shark is deleted. We likely do not want the posts associated with a deleted shark persisting in the database. To ensure that any posts associated with a given shark are eliminated when that shark is deleted, we can include the dependent option with the association.

值得考虑的一件事是,删除特定的鲨鱼后帖子会发生什么。 我们可能不希望与已删除的鲨鱼相关的帖子保留在数据库中。 为了确保在删除该鲨鱼后删除与该鲨鱼相关的所有帖子,我们可以在该关联中包括dependent选项。

Add the following code to the file to ensure that the destroy action on a given shark deletes any associated posts:

将以下代码添加到文件中,以确保对给定鲨鱼的destroy动作将删除所有关联的帖子:

~/sharkapp/app/models/shark.rb
〜/ sharkapp / app / models / shark.rb
class Shark < ApplicationRecord
  has_many :posts, dependent: :destroy
  validates :name, presence: true, uniqueness: true
  validates :facts, presence: true
end

Once you have finished making these changes, save and close the file. If you are working with nano, do this by pressing CTRL+X, Y, then ENTER.

完成这些更改后,保存并关闭文件。 如果您使用的是nano ,请按CTRL+XY ,然后按ENTER

You now have a model generated for your posts, but you will also need a controller to coordinate between the data in your database and the HTML that’s generated and presented to users.

现在,您已经为帖子生成了一个模型,但是您还需要一个控制器来协调数据库中的数据与生成并呈现给用户HTML之间的关系。

第2步-为嵌套资源创建控制器 (Step 2 — Creating a Controller for a Nested Resource)

Creating a posts controller will involve setting a nested resource route in the application’s main routing file and creating the controller file itself to specify the methods we want associated with particular actions.

创建发布控制器将涉及在应用程序的主路由文件中设置嵌套资源路由,并创建控制器文件本身以指定我们想要与特定操作关联的方法。

To begin, open your config/routes.rb file to establish the relationship between your resourceful routes:

首先,打开config/routes.rb文件以建立资源丰富的路由之间的关系:

  • nano config/routes.rb

    纳米配置/ routes.rb

Currently, the file looks like this:

当前,文件如下所示:

~/sharkapp/config/routes.rb
〜/ sharkapp / config / routes.rb
Rails.application.routes.draw do
  resources :sharks

  root 'sharks#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

We want to create a dependent relationship relationship between shark and post resources. To do this, update your route declaration to make :sharks the parent of :posts. Update the code in the file to look like the following:

我们想要在鲨鱼和职位资源之间创建一个依赖关系 。 为此,请更新您的路线声明以使:sharks:posts的父级。 更新文件中的代码,如下所示:

~/sharkapp/config/routes.rb
〜/ sharkapp / config / routes.rb
Rails.application.routes.draw do
  resources :sharks do
    resources :posts
  end
  root 'sharks#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

Save and close the file when you are finished editing.

完成编辑后,保存并关闭文件。

Next, create a new file called app/controllers/posts_controller.rb for the controller:

接下来,为控制器创建一个名为app/controllers/posts_controller.rb的新文件:

  • nano app/controllers/posts_controller.rb

    纳米应用/控制器/posts_controller.rb

In this file, we’ll define the methods that we will use to create and destroy individual posts. However, because this is a nested model, we’ll also want to create a local instance variable, @shark, that we can use to associate particular posts with specific sharks.

在此文件中,我们将定义用于创建和销毁单个帖子的方法。 但是,因为这是一个嵌套模型,所以我们还想创建一个本地实例变量@shark ,我们可以使用它来将特定帖子与特定鲨鱼相关联。

First, we can create the PostsController class itself, along with two private methods: get_shark, which will allow us to reference a particular shark, and post_params, which gives us access to user-submitted information by way of the params method.

首先,我们可以创建PostsController类本身,有两个沿private方法: get_shark ,这将使我们引用一个特定的鲨鱼,和post_params ,这让我们用的方式获得用户提交的信息PARAMS方法 。

Add the following code to the file:

将以下代码添加到文件中:

~/sharkapp/app/controllers/posts_controller.rb
〜/ sharkapp / app / controllers / posts_controller.rb
class PostsController < ApplicationController
  before_action :get_shark 

  private

  def get_shark
    @shark = Shark.find(params[:shark_id])
  end

  def post_params
    params.require(:post).permit(:body, :shark_id)
  end
end

You now have methods to get the particular shark instances with which your posts will be associated, using the :shark_id key, and the data that users are inputting to create posts. Both of these objects will now be available for the methods you will define to handle creating and destroying posts.

现在,您可以使用:shark_id键以及用户输入的用于创建帖子的数据,来获取与您的帖子相关联的特定鲨鱼实例的方法。 这两个对象现在都可用于您定义的用于处理创建和销毁帖子的方法。

Next, above the private methods, add the following code to the file to define your create and destroy methods:

接下来,在private方法上方,将以下代码添加到文件中,以定义您的createdestroy方法:

~/sharkapp/app/controllers/posts_controller.rb
〜/ sharkapp / app / controllers / posts_controller.rb
. . .
  def create
    @post = @shark.posts.create(post_params)
  end

  def destroy
    @post = @shark.posts.find(params[:id])
    @post.destroy   
  end
. . .

These methods associate @post instances with particular @shark instances, and use the collection methods that became available to us when we created the has_many association between sharks and posts. Methods such as find and create allow us to target the collection of posts associated with a particular shark.

这些方法将@post实例与特定的@shark实例相关联,并使用在我们创建鲨鱼和帖子之间的has_many关联时可用的收集方法 。 findcreate使我们可以定位与特定鲨鱼相关的职位集合。

The finished file will look like this:

完成的文件将如下所示:

~/sharkapp/app/controllers/posts_controller.rb
〜/ sharkapp / app / controllers / posts_controller.rb
class PostsController < ApplicationController
  before_action :get_shark 

  def create
    @post = @shark.posts.create(post_params)
  end

  def destroy
    @post = @shark.posts.find(params[:id])
    @post.destroy   
  end

  private

  def get_shark
    @shark = Shark.find(params[:shark_id])
  end

  def post_params
    params.require(:post).permit(:body, :shark_id)
  end
end

Save and close the file when you are finished editing.

完成编辑后,保存并关闭文件。

With your controller and model in place, you can begin thinking about your view templates and how you will organize your application’s generated HTML.

放置好控制器和模型后,您就可以开始考虑视图模板以及如何组织应用程序生成HTML。

第3步-用局部视图重组视图 (Step 3 — Reorganizing Views with Partials)

You have created a Post model and controller, so the last thing to think about from a Rails perspective will be the views that present and allow users to input information about sharks. Views are also the place where you will have a chance to build out interactivity with Stimulus.

您已经创建了Post模型和控制器,因此从Rails角度考虑的最后一件事是呈现的视图,并允许用户输入有关鲨鱼的信息。 视图也是您与Stimulus建立互动性的地方。

In this step, you will map out your views and partials, which will be the starting point for your work with Stimulus.

在此步骤中,您将绘制视图和局部视图,这将是您与Stimulus一起工作的起点。

The view that will act as the base for posts and all partials associated with posts is the sharks/show view.

用作帖子以及与帖子关联的所有部分的基础的视图是sharks/show视图。

Open the file:

打开文件:

  • nano app/views/sharks/show.html.erb

    纳米app / views / sharks / show.html.erb

Currently, the file looks like this:

当前,文件如下所示:

~/sharkapp/app/views/sharks/show.html.erb
〜/ sharkapp / app / views / sharks / show.html.erb

<%= notice %>

Name: <%= @shark.name %>

Facts: <%= @shark.facts %>

<%= link_to 'Edit', edit_shark_path(@shark) %> | <%= link_to 'Back', sharks_path %>

When we created our Post model, we opted not to generate views for our posts, since we will handle them through our sharks/show view. So in this view, the first thing we will address is how we will accept user input for new posts, and how we will present posts back to the user.

创建Post模型时,我们选择不生成帖子视图,因为我们将通过sharks/show视图处理它们。 因此,在此视图中,我们要解决的第一件事是我们如何接受用户对新帖子的输入,以及如何将帖子呈现给用户。

Note: For an alternative to this approach, please see How To Create Nested Resources for a Ruby on Rails Application, which sets up post views using the full range of Create, Read, Update, Delete (CRUD) methods defined in the posts controller. For a discussion of these methods and how they work, please see Step 3 of How To Build a Ruby on Rails Application.

注意:有关此方法的替代方法,请参见如何为Ruby on Rails应用程序创建嵌套资源 ,该方法使用在posts控制器中定义的全部Create,Read,Update,Delete (CRUD)方法来设置发布视图。 有关这些方法以及它们如何工作的讨论,请参见如何构建Ruby on Rails应用程序的 步骤3 。

Instead of building all of our functionality into this view, we will use partials — reusable templates that serve a particular function. We will create one partial for new posts, and another to control how posts are displayed back to the user. Throughout, we’ll be thinking about how and where we can use Stimulus to manipulate the appearance of posts on the page, since our goal is to control the presentation of posts with JavaScript.

与其将所有功能都构建到该视图中,我们将使用partials-用于特定功能的可重用模板。 我们将为新帖子创建一个部分,而另一部分将控制如何将帖子显示回用户。 在整个过程中,我们将考虑如何以及在何处使用Stimulus来操纵页面上帖子的外观,因为我们的目标是使用JavaScript控制帖子的显示。

First, below shark facts, add an

header for posts and a line to render a partial called sharks/posts:

首先,在shark事实下方,添加

标头作为帖子,并添加一行以显示部分名为sharks/posts

~/sharkapp/app/views/sharks/show.html.erb
〜/ sharkapp / app / views / sharks / show.html.erb
. . . 

Facts: <%= @shark.facts %>

Posts

<%= render 'sharks/posts' %> . . .

This will render the partial with the form builder for new post objects.

这将使用表单构建器为新的post对象呈现部分。

Next, below the Edit and Back links, we will add a section to control the presentation of older posts on the page. Add the following lines to the file to render a partial called sharks/all:

接下来,在“ Edit和“ Back链接下方,我们将添加一个部分来控制页面上较旧帖子的显示。 sharks/all添加到文件中以渲染名为sharks/all的部分内容:

~/sharkapp/app/views/sharks/show.html.erb
〜/ sharkapp / app / views / sharks / show.html.erb
<%= link_to 'Edit', edit_shark_path(@shark) %> |
<%= link_to 'Back', sharks_path %>

<%= render 'sharks/all' %>

The

element will be useful when we start integrating Stimulus into this file.

当我们开始将刺激集成到此文件中时,

元素将很有用。

Once you are finished making these edits, save and close the file. With the changes you’ve made on the Rails side, you can now move on to installing and integrating Stimulus into your application.

完成这些编辑后,保存并关闭文件。 通过在Rails方面所做的更改,您现在可以继续安装Stimulus并将其集成到您的应用程序中。

第4步-安装刺激 (Step 4 — Installing Stimulus)

The first step in using Stimulus will be to install and configure our application to work with it. This will include making sure we have the correct dependencies, including the Yarn package manager and Webpacker, the gem that will allow us to work with the JavaScript pre-processor and bundler webpack. With these dependencies in place, we will be able to install Stimulus and use JavaScript to manipulate events and elements in the DOM.

使用Stimulus的第一步将是安装和配置我们的应用程序以使其与之配合使用。 这将包括确保我们具有正确的依赖关系,包括Yarn程序包管理器和Webpacker ,这是使我们能够与JavaScript预处理程序和捆绑程序webpack一起使用的宝石 。 有了这些依赖关系之后,我们将能够安装Stimulus并使用JavaScript来操纵DOM中的事件和元素。

Let’s begin by installing Yarn. First, update your package list:

让我们从安装Yarn开始。 首先,更新您的包裹清单:

  • sudo apt update

    sudo apt更新

Next, add the GPG key for the Debian Yarn repository:

接下来,为Debian Yarn存储库添加GPG密钥:

  • curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -

    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt键添加-

Add the repository to your APT sources:

将存储库添加到您的APT源:

  • echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

    回声“ deb https://dl.yarnpkg.com/debian/稳定主” sudo tee /etc/apt/sources.list.d/yarn.list

Update the package database with the newly added Yarn packages:

使用新添加的Yarn软件包更新软件包数据库:

  • sudo apt update

    sudo apt更新

And finally, install Yarn:

最后,安装Yarn:

  • sudo apt install yarn

    sudo apt安装纱

With yarn installed, you can move on to adding the webpacker gem to your project.

安装了yarn ,您可以继续将webpacker gem添加到您的项目中。

Open your project’s Gemfile, which lists the gem dependencies for your project:

打开项目的Gemfile,其中列出了项目的gem依赖关系:

  • nano Gemfile

    纳米宝石文件

Inside the file, you will see Turbolinks enabled by default:

在文件内部,您将看到默认情况下启用了Turbolink:

~/sharkapp/Gemfile
〜/ sharkapp / Gemfile
. . . 
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
. . .

Turbolinks is designed to improve performance by optimizing page loads: instead of having link clicks navigate to a new page, Turbolinks intercepts these click events and makes the page request using Asynchronous JavaScript and HTML (AJAX). It then replaces the body of the current page and merges the contents of the sections, while the JavaScript window and document objects and the element persist between renders. This addresses one of the main causes of slow page load times: the reloading of CSS and JavaScript resources.

Turbolinks旨在通过优化页面负载来提高性能:Turbolinks不会拦截链接单击导航到新页面,而是拦截这些点击事件并使用异步JavaScript和HTML(AJAX)发出页面请求。 然后,它替换当前页面的正文并合并部分的内容,而JavaScript windowdocument对象以及元素在渲染之间保持不变。 这解决了页面加载时间慢的主要原因之一:CSS和JavaScript资源的重新加载。

We get Turbolinks by default in our Gemfile, but we will need to add the webpacker gem so that we can install and use Stimulus. Below the turbolinks gem, add webpacker:

默认情况下,我们在Gemfile中获得Turbolinks,但是我们将需要添加webpacker gem,以便我们可以安装和使用Stimulus。 在turbolinks gem下方,添加webpacker

~/sharkapp/Gemfile
〜/ sharkapp / Gemfile
. . . 
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
gem 'webpacker', '~> 4.x'
. . .

Save and close the file when you are finished.

完成后保存并关闭文件。

Next, add the gem to your project’s bundle with the bundle command:

接下来,使用bundle命令将gem添加到项目的bundle中:

  • bundle

This will generate a new Gemfile.lock file — the definitive record of gems and versions for your project.

这将生成一个新的Gemfile.lock文件-项目的gem和版本的Gemfile.lock记录。

Next, install the gem in the context of your bundle with the following bundle exec command:

接下来,使用以下bundle exec命令在包的上下文中安装gem:

  • bundle exec rails webpacker:install

    捆绑exec rails webpacker:安装

Once the installation is complete, we will need to make one small adjustment to our application’s content security file. This is due to the fact that we are working with Rails 5.2+, which is a Content Security Policy (CSP) restricted environment, meaning that the only scripts allowed in the application must be from trusted sources.

安装完成后,我们将需要对应用程序的内容安全文件进行一些小的调整。 这是由于我们正在使用Rails 5.2+的事实,Rails 5.2+是受内容安全策略(CSP)限制的环境,这意味着应用程序中允许的唯一脚本必须来自受信任的来源。

Open config/initializers/content_security_policy.rb, which is the default file Rails gives us for defining application-wide security policies:

打开config/initializers/content_security_policy.rb ,这是Rails为我们定义应用程序范围的安全策略提供的默认文件:

  • nano config/initializers/content_security_policy.rb

    纳米配置/初始化/ content_security_policy.rb

Add the following lines to the bottom of the file to allow webpack-dev-server — the server that serves our application’s webpack bundle — as an allowed origin:

在文件底部添加以下几行,以允许webpack-dev-server (服务于我们的应用程序的webpack软件包的服务器)作为允许的来源:

~/sharkapp/config/initializers/content_security_policy.rb
〜/ sharkapp / config / initializers / content_security_policy.rb
. . . 
Rails.application.config.content_security_policy do |policy|
  policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035' if Rails.env.development?
end

This will ensure that the webpacker-dev-server is recognized as a trusted asset source.

这将确保webpacker-dev-server被识别为可信资产来源。

Save and close the file when you are finished making this change.

完成更改后,保存并关闭文件。

By installing webpacker, you created two new directories in your project’s app directory, the directory where your main application code is located. The new parent directory, app/javascript, will be where your project’s JavaScript code will live, and it will have the following structure:

通过安装webpacker ,您在项目的app目录中创建了两个新目录,这是您的主要应用程序代码所在的目录。 新的父目录app/javascript将是项目JavaScript代码所在的目录,并且具有以下结构:


   
   
     
     
     
     
Output
├── javascript │ ├── controllers │ │ ├── hello_controller.js │ │ └── index.js │ └── packs │ └── application.js

The app/javascript directory will contain two child directories: app/javascript/packs, which will have your webpack entry points, and app/javascript/controllers, where you will define your Stimulus controllers. The bundle exec command that we just used will create the app/javascript/packs directory, but we will need to install Stimulus for the app/javascript/controllers directory to be autogenerated.

app/javascript目录将包含两个子目录: app/javascript/packs (将具有您的webpack入口点)和app/javascript/controllers (将在其中定义Stimulus 控制器) 。 我们刚刚使用的bundle exec命令将创建app/javascript/packs目录,但是我们需要安装Stimulus才能自动生成app/javascript/controllers目录。

With webpacker installed, we can now install Stimulus with the following command:

安装了webpacker ,我们现在可以使用以下命令安装Stimulus:

  • bundle exec rails webpacker:install:stimulus

    捆绑exec rails webpacker:install:stimulus

You will see output like the following, indicating that the installation was successful:

您将看到类似以下的输出,表明安装成功:


   
   
     
     
     
     
Output
. . . success Saved lockfile. success Saved 5 new dependencies. info Direct dependencies └─ [email protected] info All dependencies ├─ @stimulus/[email protected] ├─ @stimulus/[email protected] ├─ @stimulus/[email protected] ├─ @stimulus/[email protected] └─ [email protected] Done in 8.30s. Webpacker now supports Stimulus.js

We now have Stimulus installed, and the main directories we need to work with it in place. Before moving on to writing any code, we’ll need to make a few application-level adjustments to complete the installation process.

现在,我们已经安装了Stimulus,并需要使用它的主要目录。 在继续编写任何代码之前,我们需要进行一些应用程序级调整以完成安装过程。

First, we’ll need to make an adjustment to app/views/layouts/application.html.erb to ensure that our JavaScript code is available and that the code defined in our main webpacker entry point, app/javascript/packs/application.js, runs each time a page is loaded.

首先,我们需要对app/views/layouts/application.html.erb进行调整,以确保我们JavaScript代码可用,并确保在我们的主要webpacker入口点app/javascript/packs/application.js定义的代码app/javascript/packs/application.js ,每次加载页面时运行。

Open that file:

打开该文件:

  • nano app/views/layouts/application.html.erb

    纳米app / views / layouts / application.html.erb

Change the following javascript_include_tag tag to javascript_pack_tag to load app/javascript/packs/application.js:

将以下javascript_include_tag标记更改为javascript_ pack _tag以加载app/javascript/packs/application.js

~/sharkapp/app/views/layouts/application.html.erb
〜/ sharkapp / app / views / layouts / application.html.erb
. . .
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
. . .

Save and close the file when you have made this change.

进行此更改后,保存并关闭文件。

Next, open app/javascript/packs/application.js:

接下来,打开app/javascript/packs/application.js

  • nano app/javascript/packs/application.js

    纳米应用程序/javascript/packs/application.js

Initially, the file will look like this:

最初,文件将如下所示:

~/sharkapp/app/javascript/packs/application.js
〜/ sharkapp / app / javascript / packs / application.js
. . . 
console.log('Hello World from Webpacker')

import "controllers"

Delete the boilerplate code that’s there, and add the following code to load your Stimulus controller files and boot the application instance:

删除那里的样板代码,并添加以下代码以加载Stimulus控制器文件并启动应用程序实例:

~/sharkapp/app/javascript/packs/application.js
〜/ sharkapp / app / javascript / packs / application.js
. . . 
import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"

const application = Application.start()
const context = require.context("../controllers", true, /\.js$/)
application.load(definitionsFromContext(context))

This code uses webpack helper methods to require the controllers in the app/javascript/controllers directory and load this context for use in your application.

此代码使用webpack帮助程序方法来要求app/javascript/controllers目录中的app/javascript/controllers并加载此上下文以在您的应用程序中使用。

Save and close the file when you are finished editing.

完成编辑后,保存并关闭文件。

You now have Stimulus installed and ready to use in your application. Next, we’ll build out the partials that we referenced in our sharks show view — sharks/posts and sharks/all — using Stimulus controllers, targets, and actions.

现在,您已经安装了Stimulus,可以在您的应用程序中使用它了。 接下来,我们将使用Stimulus 控制器目标操作构建在“鲨鱼” show视图中引用的局部对象(“ sharks/posts和“ sharks/all

第5步—在Rails部分中使用刺激 (Step 5 — Using Stimulus in Rails Partials)

Our sharks/posts partial will use the form_with form helper to create a new post object. It will also make use of Stimulus’s three core concepts: controllers, targets, and actions. These concepts work as follows:

我们的form_with sharks/posts部分将使用form_with表单助手创建一个新的post对象。 它还将利用Stimulus的三个核心概念:控制器,目标和动作。 这些概念的工作方式如下:

  • Controllers are JavaScript classes that are defined in JavaScript modules and exported as the module’s default object. Through controllers, you have access to particular HTML elements and the Stimulus Application instance defined in app/javascript/packs/application.js.

    控制器是在JavaScript模块中定义并作为模块的默认对象导出JavaScript类。 通过控制器,您可以访问特定HTML元素和app/javascript/packs/application.js定义的Stimulus Application实例。

  • Targets allow you to reference particular HTML elements by name, and are associated with particular controllers.

    目标允许您按名称引用特定HTML元素,并且与特定的控制器相关联。
  • Actions control how DOM events are handled by controllers, and are also associated with particular controllers. They create a connection between the HTML element associated with the controller, the methods defined in the controller, and a DOM event listener.

    动作控制控制器如何处理DOM事件,并且还与特定的控制器相关联。 它们在与控制器关联HTML元素,控制器中定义的方法以及DOM事件侦听器之间创建连接。

In our partial, we’re first going to build a form as we normally would using Rails. We will then add a Stimulus controller, action, and targets to the form in order to use JavaScript to control how new posts get added to the page.

在本部分中,我们首先要像通常使用Rails一样构建一个表单。 然后,我们将在表单中添加一个Stimulus控制器,动作和目标,以便使用JavaScript控制如何将新帖子添加到页面。

First, create a new file for the partial:

首先,为局部文件创建一个新文件:

  • nano app/views/sharks/_posts.html.erb

    纳米app / views / sharks / _posts.html.erb

Inside the file, add the following code to create a new post object using the form_with helper:

在文件内部,添加以下代码以使用form_with帮助器创建一个新的post对象:

~/sharkapp/app/views/sharks/_posts.html.erb
〜/ sharkapp / app / views / sharks / _posts.html.erb
<%= form_with model: [@shark, @shark.posts.build] do |form| %>
                <%= form.text_area :body, placeholder: "Your post here" %>
                
<%= form.submit %> <% end %>

So far, this form behaves like a typical Rails form, using the form_with helper to build a post object with the fields defined for the Post model. Thus, the form has a field for the post :body, to which we’ve added a placeholder with a prompt for filling in a post.

到目前为止,此表单的行为类似于典型的Rails表单,使用form_with helper来构建具有为Post模型定义的字段的post对象。 因此,表单在post :body字段中添加了一个placeholder ,并提示您填写帖子。

Additionally, the form is scoped to take advantage of the collection methods that come with the associations between the Shark and Post models. In this case, the new post object that’s created from user-submitted data will belong to the collection of posts associated with the shark we’re currently viewing.

此外,该表单的范围仅限于利用SharkPost模型之间的关联所附带的收集方法。 在这种情况下,根据用户提交的数据创建的新post对象将属于与当前正在查看的鲨鱼相关的post的集合。

Our goal now is to add some Stimulus controllers, events, and actions to control how the post data gets displayed on the page. The user will ultimately submit post data and see it posted to the page thanks to a Stimulus action.

现在,我们的目标是添加一些Stimulus控制器,事件和操作,以控制帖子数据在页面上的显示方式。 最终,用户将通过Stimulus动作提交帖子数据并将其发布到页面上。

First, we’ll add a controller to the form called posts in a

element:

首先,我们将在

元素中的窗体中添加一个称为posts的控制器:

~/sharkapp/app/views/sharks/_posts.html.erb
〜/ sharkapp / app / views / sharks / _posts.html.erb
<%= form_with model: [@shark, @shark.posts.build] do |form| %> <%= form.text_area :body, placeholder: "Your post here" %>
<%= form.submit %> <% end %>

Make sure you add the closing

tag to scope the controller properly.

确保添加结束

标记以正确确定控制器的范围。

Next, we’ll attach an action to the form that will be triggered by the form submit event. This action will control how user input is displayed on the page. It will reference an addPost method that we will define in the posts Stimulus controller:

接下来,我们将向表单附加一个动作,该动作将由表单提交事件触发。 此操作将控制用户输入在页面上的显示方式。 它将引用一个addPost方法,该方法将在post Stimulus控制器中定义:

~/sharkapp/app/views/sharks/_posts.html.erb
〜/ sharkapp / app / views / sharks / _posts.html.erb
<%= form_with model: [@shark, @shark.posts.build], data: { action: "posts#addBody" } do |form| %> . . . <%= form.submit %> <% end %>

We use the :data option with form_with to submit the Stimulus action as an additional HTML data attribute. The action itself has a value called an action descriptor made up of the following:

我们将:data选项与form_with一起使用,以将Stimulus操作作为附加HTML数据属性提交。 动作本身具有一个称为动作描述符的值,该值由以下各项组成:

  • The DOM event to listen for. Here, we are using the default event associated with form elements, submit, so we do not need to specify the event in the descriptor itself. For more information about common element/event pairs, see the Stimulus documentation.

    要监听的DOM事件 。 在这里,我们使用与表单元素Submit关联的默认事件,因此我们不需要在描述符本身中指定事件。 有关常见元素/事件对的更多信息,请参见“ 激励”文档 。

  • The controller identifier, in our case posts.

    控制器标识符 ,在我们的例子中是posts

  • The method that the event should invoke. In our case, this is the addBody method that we will define in the controller.

    事件应调用的方法 。 在我们的例子中,这是我们将在控制器中定义的addBody方法。

Next, we’ll attach a data target to the user input defined in the :body