Rails form_附教程 | 引导轨

“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

action="/welcome/index" accept-charset="UTF-8" method="post"> type="hidden" name="authenticity_token" value="zOt30hNDyv2GLIUHeHmpUksAk8eujPFwbd6r7-pIpHigC6TLF9eAplosFKQxWF2N65NwKjDCurP5y3c1WYUwmw" autocomplete="off"> Form contents

  • 默认的 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

action="/welcome/book_endpoint" accept-charset="UTF-8" method="post"> type="hidden" name="authenticity_token" value="AsfAGgNmd52Y6AUjbhtulwVtc6Q8r9r6U0wkKRAqnwbzlpeIK0x29NOzUDpcJrxAEht6njABQ_WoCdOB0Haq_Q" autocomplete="off">
for="book_title">Title is: type="text" name="bookRails form_with tutorial | Bootrails" id="book_title">
for="book_text">Text is: name="book[text]" id="book_text">
for="book_isbn">Isbn is: type="number" name="book[isbn]" id="book_isbn">
type="submit" name="commit" value="Search" data-disable-with="Search">

  • 请注意,“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 %> action="/fruits" accept-charset="UTF-8" method="post"> type="hidden" name="authenticity_token" value="ZoY6D8B5iEd5Pp2PEWt-QHEYUgmVTQwz4omUz_e42g2DSFl-N5cZvmj54aVZVh8ZkXgmF7vs2FBjxXOsuCnctg" autocomplete="off">
style="display: block" for="fruit_name">Name type="text" name="fruit[name]" id="fruit_name">
type="submit" name="commit" value="Create Fruit" data-disable-with="Create Fruit">

渲染如下:

1
2
3
4
5
6
7
8
9
10
11
12
 action="/fruits" accept-charset="UTF-8" method="post">
   type="hidden" name="authenticity_token" value="ZoY6D8B5iEd5Pp2PEWt-QHEYUgmVTQwz4omUz_e42g2DSFl-N5cZvmj54aVZVh8ZkXgmF7vs2FBjxXOsuCnctg" autocomplete="off">

  
style="display: block" for="fruit_name">Name type="text" name="fruit[name]" id="fruit_name">
type="submit" name="commit" value="Create Fruit" data-disable-with="Create Fruit">

刚从 model: fruit,Rails 能够猜测:

  • 端点 URL
  • 方法
  • 每个字段的名称和id
  • 考虑到我们之前看到的情况,其他一切都不足为奇

对于很多人来说这可能太多了,但是您可以看到 Rails 如何专注于模型和约定。

请注意,您不必“必须”始终遵循 Rails 方式,只需按照您认为更舒服的方式进行编码即可。

也许有一天,您会发现遵循惯例比重复相同的无聊样板更容易。 但我的建议是“不要太早尝试”,如果它不适合你的心态,也许根本不尝试。

结论

正如我们在本文中所做的那样,尝试至少阅读一次 Rails 抽象和实际浏览器渲染之间发生的情况,有助于深入理解事物的工作原理。

我没有尝试像我那样提交表格 导轨和表格文章,因此您可以尝试查看 Rails 控制台中发生的情况作为练习。

我希望你今天学到了新东西!

最好的,

大卫。

Leave a Reply

Your email address will not be published. Required fields are marked *

近期新闻​

编辑精选​