“form_with”被称为表单助手,这意味着它是构建众所周知的标准 HTML 表单的抽象。
需要form_with
首先,我们应该提到 为什么我们无论如何都需要一个帮手。 毕竟,Web 表单与 Web 本身一样古老,将其包装在 Ruby 或 Rails 帮助器中不会让事情变得更复杂吗? 乍一看,你是完全正确的。
但请记住 铁轨哲学。 Rails价值集成系统,这意味着在某一时刻我们必须依赖浏览器和服务器之间的强大协作。 这种合作(部分)是由帮助者确保的
如果没有帮助者,您将不得不关心:
边注 :对 Rails 的许多批评是该工具将抽象推得太远,我在某种程度上同意这一点。 多少抽象对您来说“足够好”完全取决于您(或您的技术主管)。
从头开始的 Rails 教程
那么让我们从头开始教程。
我将在本教程中使用的工具:
1
2
3
ruby -v # 3.3.0
bundle -v # 2.4.10
node -v # 20.9.0
然后让我们进入常用工作区的根目录,开始构建一个全新的 Rails 应用程序:
1
2
3
4
5
mkdir formwith && cd formwith
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'rails', '7.1.3'" >> Gemfile
bundle install
bundle exec rails new . --force
请注意,这里我没有使用 --minimal
标志-参见 此处的选项。 它将删除 Hotwire、Stimulus 等——浏览器和服务器之间的协作 那么就会有所不同。 我想在本教程中坚持使用普通的旧 Rails。
创建数据层
表单用于将数据发送到服务器,因此向我们的应用程序添加一些模型和数据会更有意义。
假设我们有一些带有标题、描述和 isbn 的书籍(isbn 是书籍的企业 ID)。
1
bin/rails generate model Book title:string body:text isbn:integer --no-test-framework
迁移文件已创建在 db/migrate/20240131201925_create_books.rb
– 这个数字是一个时间戳,当然你会有另一个。
1
2
3
4
5
6
7
8
9
10
11
class CreateBooks < ActiveRecord::Migration[7.1]
def change
create_table :books do |t|
t.string :title
t.text :body
t.integer :isbn
t.timestamps
end
end
end
默认视图放置表单的位置
这里只有标准 Rails。 在终端中,转到应用程序的根目录,然后粘贴以下命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
# Create a default controller
echo "class WelcomeController < ApplicationController" > app/controllers/welcome_controller.rb
echo "end" >> app/controllers/welcome_controller.rb
# Create a default route
echo "Rails.application.routes.draw do" > config/routes.rb
echo ' get "welcome/index"' >> config/routes.rb
echo ' root to: "welcome#index"' >> config/routes.rb
echo 'end' >> config/routes.rb
# Create a default view
mkdir app/views/welcome
echo 'form_with tutorial
' > app/views/welcome/index.html.erb
然后创建数据库,
1
bin/rails db:create db:migrate
然后输入以下命令启动本地 Rails 服务器:
并检查“form_with教程”是否显示在浏览器中的localhost:3000
发送数据的端点
打开 routes.rb
文件,并添加发送数据的路径,如下所示:
1
2
3
4
5
Rails.application.routes.draw do
get "welcome/index"
post "welcome/book_endpoint", as: "book_endpoint" # add this line
root to: "welcome#index"
end
并在WelcomeController中添加相应的方法:
1
2
3
4
5
6
7
class WelcomeController < ApplicationController
# Add this method
def book_endpoint
end
end
现在在 localhost:3000/rails/info/routes 打开浏览器,您应该看到端点。
边注 :最好遵循 REST 约定,Rails 可以在 paths.rb 文件中帮助做到这一点。 出于演示目的,我们坚持使用明确、更简单的路线来发送数据。
使用… form_with 构建第一个表单
现在是时候看看如何 form_with
可以帮助构建表格。
1
2
3
4
5
6
<%# inside app/views/welcome/index.html.erb %>
form_with tutorial
<%= form_with do |myform| %>
Form contents
<% end %>
它呈现一个空表单,如下所示:
1
2
3
4
5
6
7
8
9
10
form_with tutorial
- 默认的 HTTP 方法是
post
- 安全令牌由 Rails 构建
- 自动设置 UTF-8 字符集
- 在 中,我们有一个
myform
有助于构建将发送到服务器的数据的对象
现实世界中的 form_with
让我们添加必填字段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%# inside app/views/welcome/index.html.erb %>
form_with tutorial
<%= form_with scope: "book", url: book_endpoint_path, method: :post do |myform| %>
<%= myform .label :title, "Title is:" %>
<%= myform.text_field :title %>
<%= myform.label :text, "Text is:" %>
<%= myform.text_area :text %>
<%= myform.label :isbn, "Isbn is:" %>
<%= myform.number_field :isbn %>
<%= myform.submit "Search" %>
<% end %>
它呈现以下 HTML :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
form_with tutorial
- 请注意,“url”和“method”在块声明中显式设置
- 请注意,您可以在表单块内混合使用 HTML 和 Rails 帮助程序
- 请注意,“name”和“id”是为每个字段明确设置的
- 请注意,对于提交字段,“commit”是默认名称。 如果有多个提交字段,我们可以明确为每个提交设置不同的名称。
form_with 使用模型
现在让我们使用 Rails 脚手架来欺骗一下。
假设我们想要创建、阅读、更新或删除一本书,而不是一本书 水果。
1
bin/rails generate scaffold fruits name:string
它将生成迁移、模型、控制器和视图(是的,仅适用于水果)。
现在停止本地服务器并运行
1
2
bin/rails db:migrate
bin/rails server
并转到 localhost:3000/fruits/new
打开 app/views/fruits/_form.html.erb
你应该看到这样的东西
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%= form_with(model: fruit) do |form| %>
<%= form.label :name, style: "display: block" %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
渲染如下:
1
2
3
4
5
6
7
8
9
10
11
12
刚从 model: fruit
,Rails 能够猜测:
- 端点 URL
- 方法
- 每个字段的名称和id
- 考虑到我们之前看到的情况,其他一切都不足为奇
对于很多人来说这可能太多了,但是您可以看到 Rails 如何专注于模型和约定。
请注意,您不必“必须”始终遵循 Rails 方式,只需按照您认为更舒服的方式进行编码即可。
也许有一天,您会发现遵循惯例比重复相同的无聊样板更容易。 但我的建议是“不要太早尝试”,如果它不适合你的心态,也许根本不尝试。
结论
正如我们在本文中所做的那样,尝试至少阅读一次 Rails 抽象和实际浏览器渲染之间发生的情况,有助于深入理解事物的工作原理。
我没有尝试像我那样提交表格 导轨和表格文章,因此您可以尝试查看 Rails 控制台中发生的情况作为练习。
我希望你今天学到了新东西!
最好的,
大卫。