使用 React 和 Ruby on Rails 构建 CRUD 接口
介绍
JavaScript 世界目前处于动荡之中。每天都会出现新的框架,开发人员对应该选择哪些工具感到困惑,并且构建用户界面正在经历巨大的变化。最重要的是,我们 Rails 开发人员知道 .erb 视图也过时了——并且被更复杂的基于 JavaScript 的框架所取代。考虑到所有这些,选择一项值得坚持的东西可能很困难。
幸运的是,Facebook 的React带来了一线希望,它承诺提供一种构建用户界面的新方法。更棒的是,Rails 可以无缝集成,而且使用 React 可以轻松设置 Rails API 应用程序并构建其视图层。那么,让我们来看看如何使用 React 构建一个简单的 Rails API,以适应单个模型的创建、读取、更新和删除功能。
设置基本 Rails API
建立模型
我们将采用不同的方法来构建应用程序架构。我们将仅使用 Rails 来呈现 JSON 数据,而 React 将处理视图和数据显示。这将使 Rails 应用程序与视图层分离。
首先,让我们初始化一个空的 rails 应用程序:
$ rails new item_cart
现在,让我们创建将为其构建 CRUD 接口的模型:
$ rails g model Item name:string description:text
这将创建一个具有名称和描述属性的模型,并为其进行数据库迁移。我们只需将模型添加到数据库架构中。
$ rake db:migrate
添加一些种子数据
现在是时候用一些示例数据填充我们的数据库了!我们需要它来确保我们要实现的功能正常运行。以下脚本将用 10 个任意项目填充我们的数据库。
#db/seeds.rb
10.times { Item.create!(name: "Item", description: "I am a description.") }
$ rake db:seed
设置控制器
是时候转到控制器了。首先,我们将安装响应者gem,这将使我们能够将respond_to规则应用于控制器中的所有操作,从而使代码更加 DRY。将 gem 放入 gemfile 中并打包:
gem 'responders'
$ bundle
其次,我们将对应用程序控制器进行一些小的调整。除了抛出异常之外,我们还将使控制器抛出一个空会话,因为我们将请求 json,这与 html(默认情况下请求)不同。
#application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
end
因为这是一个基于 API 的应用程序,所以我们将使用命名空间来构造控制器。按照惯例,我们必须将不同命名空间的控制器放在与其命名空间相对应的文件夹中。例如,属于 api 命名空间的所有控制器都必须放在名为“api”的文件夹中。在“controllers”文件夹中(在我们的应用程序中),我们将创建一个名为api的文件夹,并在其中创建另一个名为v1的文件夹:
app/controllers/api/v1
在app/controllers/api/v1目录中,我们将创建两个控制器。base_controller 将具有适用于所有基于 API 的控制器的全局规则。
#base_controller.rb
class Api::V1::BaseController < ApplicationController
respond_to :json
end
respond_to 方法确保从基本控制器继承的控制器的所有操作都将以 JSON 响应。这是构建基于 JSON 的 API 的标准方法。完成基本控制器后,我们可以为 Item 模型创建一个控制器。我们将使控制器从基本控制器继承并放置标准索引、创建更新和销毁操作。
#items_controller.rb
class Api::V1::ItemsController < Api::V1::BaseController
def index
respond_with Item.all
end
def create
respond_with :api, :v1, Item.create(item_params)
end
def destroy
respond_with Item.destroy(params[:id])
end
def update
item = Item.find(params["id"])
item.update_attributes(item_params)
respond_with item, json: item
end
private
def item_params
params.require(:item).permit(:id, :name, :description)
end
end
respond_with 方法是responders gem 的一部分,它将返回一个 JSON 对象,其中包含控制器中每个操作的结果。
控制器的路由必须考虑到它位于两个命名空间内:API 和 V1。我们将使用命名空间方法来实现这一点。
路由控制器
#app/config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :items, only: [:index, :create, :destroy, :update]
end
end
end
要查看一切是否正常,请访问:
http://localhost:3000/api/v1/items.json
如果您看到 JSON 对象数组,那么一切就绪了!
我们已经完成了 API,但是我们将在哪里渲染 React?让我们构建一个应用程序将引导我们到的静态视图。首先,我们必须创建一个专门负责渲染静态视图的控制器。
#app/controllers/site_controller.rb
class SiteController < ApplicationController
def index
end
end
#app/config/routes.rb
Rails.application.routes.draw do
root to: 'site#index'
将 React 添加到 Rails
将react-rails添加到 Gemfile。
gem 'react-rails'
$ bundle
$ rails g react:install
react:install 生成器将自动将 react JavaScript 库包含在你的资产管道中
$ rails g react:install
create app/assets/javascripts/components
create app/assets/javascripts/components/.gitkeep
insert app/assets/javascripts/application.js
insert app/assets/javascripts/application.js
insert app/assets/javascripts/application.js
create app/assets/javascripts/components.js
与 JQuery 和其他 JavaScript 库一样,react 和 react_ujs 也包含在资源管道中。assets /javascripts目录中的 components 文件夹是我们存储组件的地方。说到组件,这些是 React 框架的构建块。它们用于分隔用户界面的不同部分,并以父子关系构建,类似于嵌套的 AngularJS 控制器的工作方式。
例如,假设您要构建一个包含正文、标题和项目列表的简单布局。其层次结构如下:
< Main/>渲染< Header/>和< Body/>,并将信息向下发送到层次结构。< Header/>可以接收有关当前用户和菜单的信息,而< Body/>可以接收项目数组。< items/>组件将获取信息并创建一个< item/>组件列表,该列表将包含有关每个单个对象的数据。< Attributes/>组件将包含有关项目的信息,而< Actions/>将包含删除和编辑按钮。
为了让 Rails 渲染 React 组件,我们需要将 react_component 视图助手添加到我们的根路由。
#app/views/site/index.html.erb
<%= react_component 'Main' %>
react_component是 react-rails 的一部分。在本例中,它用于将assets 目录中 components 文件夹中名为Main的组件放入视图中。
第一个组件
我们需要做的第一件事是在我们的组件文件夹中设置一个 jsx 文件。
// app/assets/javascripts/components/_main.js.jsx
var Main = React.createClass({
render() {
return (
<div>
<h1>Hello, World!</h1>
</div>
);
}
});
React 组件中的js.jsx的工作方式与Rails 中的html.erb相同;它是用于识别框架视图文件的扩展。此组件只有一个方法;render()。在本例中,它用于将静态 html 返回到页面。render()方法还会触发父组件的所有子组件的render(),最终在页面上打印所有组件。每个 React 组件只能返回一个元素,因此 return 语句中的所有 jsx 元素都需要位于一个包装器 div 中。
<Main />组件有两个子组件:<Header />和<Body />。我们先从<Header />开始。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~