如何为 Ruby on Rails 应用程序创建嵌套资源

介绍

Ruby on Rails是一个用 Ruby编写的Web应用程序框架,为开发人员提供了对应用程序开发的有观点的方法。与Rails合作可以为开发人员提供:

  • 处理路由、状态数据和资产管理等事物的惯例。 * 在 model-view-controller(MCV)架构模式中有坚实的基础,它将应用程序的逻辑,位于模型中,与应用程序信息的呈现和路由分开。

随着 Rails 应用程序的复杂性增加,您可能会使用多个模型工作,这些模型代表您的应用程序的业务逻辑和与数据库的界面。

在本教程中,您将建立在现有 Rails 应用程序上,该应用程序为用户提供关于鲨鱼的事实。 该应用程序已经有处理鲨鱼数据的模型,但您将为关于个别鲨鱼的帖子添加一个嵌套的资源。

前提条件

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

步骤 1 - Scaffolding 巢的模型

我们的应用将利用主动记录_联合,在 " 鲨鱼 " 模式和 " 后 " 模式之间建立关系:职位将属于特定鲨鱼,每个鲨鱼可以有多个职位。 因此,我们的 " Shark " 和 " Post " 模式将通过[belongs-to ' (https://guides.rubyonrails.org/association_basics.html# the-belongs-to-association)和[has-many' (https://guides.rubyonrails.org/association_basics.html the-has-many-association)协会联系起来.

以这种方式建立应用程序的第一步是建立一个 " 后 " 模式和相关资源。 为此,我们可以使用`铁路生成脚手架'命令,这将给我们一个模型、一个数据库迁移来改变数据库计划、一个控制器、一套完整的视图来管理标准创建、读取、更新和删除(CRUD)操作以及部分、助手和测试的模板。 我们需要修改这些资源,但使用 " 脚手架 " 命令将节省我们一些时间和精力,因为它会产生一个我们可以用作起点的结构.

首先,请确保您位于您在前提条件下创建的 Rails 项目的 sharkapp 目录中:

1cd sharkapp

用以下命令创建您的邮件资源:

1rails generate scaffold Post body:text shark:references

在)。

一旦运行该命令,您将看到输出确认 Rails 为该应用程序生成的资源。在继续前,您可以检查数据库迁移文件以查看模型和数据库表之间现有的关系。

1cat db/migrate/20190805132506_create_posts.rb

您将看到以下结果:

 1[secondary_label Output]
 2class CreatePosts < ActiveRecord::Migration[5.2]
 3  def change
 4    create_table :posts do |t|
 5      t.text :body
 6      t.references :shark, foreign_key: true
 7
 8      t.timestamps
 9    end
10  end
11end

正如您所看到的,表中包含一个鲨鱼外密钥的列,此密钥将以model_name_id的形式出现,在我们的情况下,则是shark_id

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

1cat app/models/post.rb
1[secondary_label Output]
2class Post < ApplicationRecord
3  belongs_to :shark
4end

belongs_to 关联建立了模型之间的关系,其中声明模型的单个实例属于命名模型的单个实例。

除了设置这种关系外,该命令)的 How To Build a Ruby on Rails Application

这是一个有用的开始,但我们需要配置一些额外的路由和巩固Shark模型的 Active Record 关联,以便我们的模型和路径之间的关系按期工作。

步骤 2 – 指定父母模型的嵌套路径和协会

Rails已经在我们的Post模型中设置了belongs_to关联,由于rails generate scaffold命令中的:references关键字,但为了使这种关系正常运作,我们需要在我们的Shark模型中指定一个has_many关联,我们还需要对Rails给我们的默认路由进行更改,以便使邮件资源成为鲨鱼资源的孩子。

若要在Shark模型中添加has_many关联,请使用nano或您最喜欢的编辑器打开app/models/shark.rb:

1nano app/models/shark.rb

将下列行添加到文件中,以建立鲨鱼和帖子的关系:

1[label ~/sharkapp/app/models/shark.rb]
2class Shark < ApplicationRecord
3  has_many :posts
4  validates :name, presence: true, uniqueness: true
5  validates :facts, presence: true
6end

这里值得考虑的一件事是,一旦某个特定鲨鱼被删除,会发生什么。我们可能不希望与已删除的鲨鱼相关的帖子继续存在于数据库中。

将以下代码添加到文件中,以确保对特定鲨鱼的破坏操作删除任何相关的帖子:

1[label ~/sharkapp/app/models/shark.rb]
2class Shark < ApplicationRecord
3  has_many :posts , dependent: :destroy
4  validates :name, presence: true, uniqueness: true
5  validates :facts, presence: true
6end

一旦你完成了这些更改,保存并关闭文件. 如果你使用nano,你可以通过按CTRL+X,Y,然后ENTER来做到这一点。

接下来,打开你的config/routes.rb文件来修改你的资源丰富的路径之间的关系:

1nano config/routes.rb

目前,檔案看起來如下:

1[label ~/sharkapp/config/routes.rb]
2Rails.application.routes.draw do
3  resources :posts 
4  resources :sharks
5
6  root 'sharks#index'
7  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
8end

当前的代码建立了我们的路径之间的独立关系,当我们想表达的是鲨鱼和他们的相关帖子之间的 依赖关系

让我们更新我们的路线声明,使 :sharks 成为 :posts 的母子。

1[label ~/sharkapp/config/routes.rb]
2Rails.application.routes.draw do
3  resources :sharks do
4    resources :posts
5  end
6  root 'sharks#index'
7  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
8end

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

有了这些更改,您可以继续更新您的帖子控制器。

步骤 3 – 更新邮件控制器

我们的模型之间的关联给了我们方法,我们可以用来创建与特定的鲨鱼相关的新邮件实例。

打开邮件控制器文件:

1nano app/controllers/posts_controller.rb

目前,檔案看起來如下:

 1[label ~/sharkapp/controllers/posts_controller.rb]
 2class PostsController < ApplicationController
 3  before_action :set_post, only: [:show, :edit, :update, :destroy]
 4
 5  # GET /posts
 6  # GET /posts.json
 7  def index
 8    @posts = Post.all
 9  end
10
11  # GET /posts/1
12  # GET /posts/1.json
13  def show
14  end
15
16  # GET /posts/new
17  def new
18    @post = Post.new
19  end
20
21  # GET /posts/1/edit
22  def edit
23  end
24
25  # POST /posts
26  # POST /posts.json
27  def create
28    @post = Post.new(post_params)
29
30    respond_to do |format|
31      if @post.save
32        format.html { redirect_to @post, notice: 'Post was successfully created.' }
33        format.json { render :show, status: :created, location: @post }
34      else
35        format.html { render :new }
36        format.json { render json: @post.errors, status: :unprocessable_entity }
37      end
38    end
39  end
40
41  # PATCH/PUT /posts/1
42  # PATCH/PUT /posts/1.json
43  def update
44    respond_to do |format|
45      if @post.update(post_params)
46        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
47        format.json { render :show, status: :ok, location: @post }
48      else
49        format.html { render :edit }
50        format.json { render json: @post.errors, status: :unprocessable_entity }
51      end
52    end
53  end
54
55  # DELETE /posts/1
56  # DELETE /posts/1.json
57  def destroy
58    @post.destroy
59    respond_to do |format|
60      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
61      format.json { head :no_content }
62    end
63  end
64
65  private
66    # Use callbacks to share common setup or constraints between actions.
67    def set_post
68      @post = Post.find(params[:id])
69    end
70
71    # Never trust parameters from the scary internet, only allow the white list through.
72    def post_params
73      params.require(:post).permit(:body, :shark_id)
74    end
75end

与我们的鲨鱼控制器一样,这个控制器的方法与相关的后'级的情况是有效的。 例如,新'方法创造了后'类的新实例,index ' 方法抓住了该类的所有实例,而set-post'方法则使用find'和params'来通过id'选择某一特定员额。 但是,如果我们希望我们的邮局事件与特定的鲨鱼事件有关,那么就需要修改这一守则,因为`邮局 ' 类别目前作为一个独立实体运作.

我们的修改将使用两件事:

  • 联合国 当我们在我们的模式中加入 " 所属协会 " 和 " 众多协会 " 时,我们可以利用的方法。 具体而言,我们现在可以使用[`建设 ' 方法(https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html# method-i-has_many) 感谢我们在 " 鲨鱼 " 模式中界定的 " 许多 " 协会。 这种方法将使我们能够利用我们的 " 后方 " 数据库中存在的 " shark-id " 外国密钥,建立一个与特定鲨鱼物体有关的后方物体库。
  • 联合国 当我们创建一条筑巢的 " 后站 " 路线时,可以找到的路线和路线帮助者。 关于在资源之间创建嵌入式关系时可以使用的完整实例路径列表,请参见 [Rails documents] (https://guides.rubyonrails.org/routing.html# nested-resources). 现在,我们只需知道,对于每一个具体的鲨鱼——比如 " 鲨鱼/1 " ——将有一个与该鲨鱼有关的员额的相关路线: " 鲨鱼1/后 " 。 还将有 " shark_posts_path (@shark) " 和 " edit_sharks_posts_path (@shark) " 等指代这些被筑巢的路线的路由助手。 .

在文件中,我们将开始写一个方法,‘get_shark’,在控制器中的每个操作之前运行。这个方法将创建一个本地的‘@shark’实例变量,通过找到一个鲨鱼实例的‘shark_id’。

在文件底部的其他私人方法之上,添加以下方法:

1[label ~/sharkapp/controllers/posts_controller.rb]
2. . . 
3private
4  def get_shark
5    @shark = Shark.find(params[:shark_id])
6  end
7  # Use callbacks to share common setup or constraints between actions.
8. . .

接下来,在现有过滤器之前,将相应的过滤器添加到文件的 顶部 :

1[label ~/sharkapp/controllers/posts_controller.rb]
2class PostsController < ApplicationController
3  before_action :get_shark

这将确保get_shark在文件中定义的每个操作之前运行。

接下来,您可以使用此@shark实例重写索引方法,而不是抓取邮件类的所有实例,我们希望此方法返回与特定鲨鱼实例相关的所有邮件实例。

更改索引方法,看起来像这样:

1[label ~/sharkapp/controllers/posts_controller.rb]
2. . .
3  def index
4    @posts = @shark.posts
5  end
6. . .

方法将需要类似的修订,因为我们希望新的邮件实例与特定的鲨鱼相关联。

更改方法看起来像这样:

1[label ~/sharkapp/controllers/posts_controller.rb]
2. . . 
3  def new
4    @post = @shark.posts.build
5  end
6. . .

此方法会创建与get_shark方法的特定鲨鱼实例相关的帖子对象。

接下来,我们将解决与最紧密相关的方法:创建创建方法做两件事:它使用用户在表格中输入的参数构建一个新的帖子实例,如果没有错误,它将该实例保存,并使用路由助手将用户重定向到他们可以看到新帖子的位置。

更新创建方法,看起来像这样:

 1[label ~/sharkapp/controllers/posts_controller.rb]
 2  def create
 3    @post = @shark.posts.build(post_params)
 4
 5        respond_to do |format|
 6         if @post.save  
 7            format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' }
 8            format.json { render :show, status: :created, location: @post }
 9         else
10            format.html { render :new }
11            format.json { render json: @post.errors, status: :unprocessable_entity }
12      end
13    end
14  end

接下来,看看更新方法. 此方法使用一个@post实例变量,而该方法本身没有明确设置。

看看文件顶部的过滤器,第二个自动生成的before_action过滤器提供了答案:

1[label ~/sharkapp/controllers/posts_controller.rb]
2class PostsController < ApplicationController
3  before_action :get_shark
4  before_action :set_post, only: [:show, :edit, :update, :destroy]
5  . . .

该)从set_post方法中采用一个@post变量,该方法与我们的其他私人方法一起列出get_shark方法,目前看起来如下:

1[label ~/sharkapp/controllers/posts_controller.rb]
2. . . 
3private
4. . . 
5  def set_post
6    @post = Post.find(params[:id])
7  end
8. . .

根据我们在档案中别处使用的方法, 我们需要修改这个方法, 在此铭记)之间的关联,我们的每一个后例都是与特定鲨鱼有关的物品集合的一部分。 因此,在查询某个特定的帖子时,我们会查询与某个特定的鲨鱼有关的帖子的收集情况.

更新「set_post」以看起來像這樣:

1[label ~/sharkapp/controllers/posts_controller.rb]
2. . . 
3private
4. . . 
5  def set_post
6    @post = @shark.posts.find(params[:id])
7  end
8. . .

相反,我们在与特定的鲨鱼相关的帖子集中搜索一个匹配的id,而不是通过id找到整个Post类的特定实例。

随着该方法的更新,我们可以看看更新破坏方法。

更新方法使用@post实例变量从set_post,并与用户在编辑表单中输入的post_params一起使用。如果成功,我们希望 Rails 将用户送回与特定鲨鱼相关的帖子的索引视图。

在这种情况下,我们唯一需要做的更改是),这将重定向到所选鲨鱼的帖子的索引`视图:

 1[label ~/sharkapp/controllers/posts_controller.rb]
 2. . . 
 3  def update
 4    respond_to do |format|
 5      if @post.update(post_params)
 6        format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' }
 7        format.json { render :show, status: :ok, location: @post }
 8      else
 9        format.html { render :edit }
10        format.json { render json: @post.errors, status: :unprocessable_entity }
11      end
12    end
13  end
14. . .

接下来,我们将对)`:

 1[label ~/sharkapp/controllers/posts_controller.rb]
 2. . . 
 3  def destroy
 4    @post.destroy
 5     respond_to do |format|
 6      format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' }
 7      format.json { head :no_content }
 8    end
 9  end
10. . .

这是我们要做的最后一个更改,你现在有一个类似于此的帖子控制器文件:

 1[label ~/sharkapp/controllers/posts_controller.rb]
 2class PostsController < ApplicationController
 3  before_action :get_shark
 4  before_action :set_post, only: [:show, :edit, :update, :destroy]
 5
 6  # GET /posts
 7  # GET /posts.json
 8  def index
 9    @posts = @shark.posts
10  end
11
12  # GET /posts/1
13  # GET /posts/1.json
14  def show
15  end
16
17  # GET /posts/new
18  def new
19    @post = @shark.posts.build
20  end
21
22  # GET /posts/1/edit
23  def edit
24  end
25
26  # POST /posts
27  # POST /posts.json
28  def create
29    @post = @shark.posts.build(post_params)
30
31        respond_to do |format|
32         if @post.save  
33            format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' }
34            format.json { render :show, status: :created, location: @post }
35         else
36            format.html { render :new }
37            format.json { render json: @post.errors, status: :unprocessable_entity }
38      end
39    end
40  end
41
42  # PATCH/PUT /posts/1
43  # PATCH/PUT /posts/1.json
44  def update
45    respond_to do |format|
46      if @post.update(post_params)
47        format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' }
48        format.json { render :show, status: :ok, location: @post }
49      else
50        format.html { render :edit }
51        format.json { render json: @post.errors, status: :unprocessable_entity }
52      end
53    end
54  end
55
56  # DELETE /posts/1
57  # DELETE /posts/1.json
58  def destroy
59    @post.destroy
60    respond_to do |format|
61      format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' }
62      format.json { head :no_content }
63    end
64  end
65
66  private
67
68   def get_shark
69     @shark = Shark.find(params[:shark_id])
70   end
71    # Use callbacks to share common setup or constraints between actions.
72    def set_post
73      @post = @shark.posts.find(params[:id])
74    end
75
76    # Never trust parameters from the scary internet, only allow the white list through.
77    def post_params
78      params.require(:post).permit(:body, :shark_id)
79    end
80end

控制器管理如何将信息从视图模板传输到数据库,反之亦然. 我们的控制器现在反映了我们SharkPost模型之间的关系,其中帖子与特定鲨鱼相关联。

步骤4:修改观点

我们的视图模板修订将涉及更改与帖子相关的模板,以及更改我们的鲨鱼显示视图,因为我们希望用户看到与特定鲨鱼相关的帖子。

让我们从我们的帖子的基础模板开始:在多个帖子模板中重复使用的部分表格

1nano app/views/posts/_form.html.erb

相反,我们只将post模型转移到form_with表单助手中,我们将通过sharkpost模型,将post设置为儿童资源。

更改文件的第一行看起来像这样,反映了我们的鲨鱼和邮件资源之间的关系:

1[label ~/sharkapp/views/posts/_form.html.erb]
2<%= form_with(model: [@shark, post], local: true) do |form| %>
3. . .

接下来,删除列出相关鲨鱼的shark_id的部分,因为这不是视图中必需的信息。

完成的表格,完整的编辑到第一行,没有删除的shark_id部分,将看起来像这样:

 1[label ~/sharkapp/views/posts/_form.html.erb]
 2<%= form_with(model: [@shark, post], local: true) do |form| %>
 3  <% if post.errors.any? %>
 4    <div id="error_explanation">
 5      <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
 6
 7      <ul>
 8      <% post.errors.full_messages.each do |message| %>
 9        <li><%= message %></li>
10      <% end %>
11      </ul>
12    </div>
13  <% end %>
14
15  <div class="field">
16    <%= form.label :body %>
17    <%= form.text_area :body %>
18  </div>
19
20  <div class="actions">
21    <%= form.submit %>
22  </div>
23<% end %>

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

接下来,打开索引视图,该视图将显示与特定鲨鱼相关的帖子:

1nano app/views/posts/index.html.erb

借助 rails generate scaffold命令,Rails 生成了模板中更好的部分,完整的表显示了每个帖子的身体字段及其相关的鲨鱼

然而,与我们已经修改的其他代码一样,这个模板将帖子视为独立实体,当我们希望利用我们模型之间的关联以及这些关联给我们的集合和辅助方法时。

在表的体内,执行以下更新:

首先,更新「post.shark」到「post.shark.name」,以便表中包含相关鲨鱼的名称字段,而不是识别鲨鱼对象本身的信息:

1[label ~/sharkapp/app/views/posts/index.html.erb]
2. . . 
3  <tbody>
4    <% @posts.each do |post| %>
5      <tr>
6        <td><%= post.body %></td>
7        <td><%= post.shark.name %></td>
8. . .

接下来,更改显示重定向,将用户导向相关鲨鱼的显示视图,因为他们很可能想要一种方法来返回原来的鲨鱼。我们可以使用我们在控制器中设置的@shark实例变量,因为Rails使控制器中创建的实例变量可供所有视图使用。

更新此行到以下:

1[label ~/sharkapp/app/views/posts/index.html.erb]
2. . . 
3  <tbody>
4    <% @posts.each do |post| %>
5      <tr>
6        <td><%= post.body %></td>
7        <td><%= post.shark.name %></td>
8        <td><%= link_to 'Show Shark', [@shark] %></td>

在下一行中,我们希望确保用户在编辑帖子时被引导到正确的嵌入式路径,这意味着而不是被引导到posts/post_id/edit,用户将被引导到sharks/shark_id/posts/post_id/edit

更新编辑行以显示如下:

1[label ~/sharkapp/app/views/posts/index.html.erb]
2. . . 
3  <tbody>
4    <% @posts.each do |post| %>
5      <tr>
6        <td><%= post.body %></td>
7        <td><%= post.shark.name %></td>
8        <td><%= link_to 'Show Shark', [@shark] %></td>
9        <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>

接下来,让我们将类似的更改添加到破坏链接中,在字符串中更新其功能,并添加我们的鲨鱼帖子资源:

 1[label ~/sharkapp/app/views/posts/index.html.erb]
 2. . . 
 3  <tbody>
 4    <% @posts.each do |post| %>
 5      <tr>
 6        <td><%= post.body %></td>
 7        <td><%= post.shark.name %></td>
 8        <td><%= link_to 'Show Shark', [@shark] %></td>
 9        <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
10        <td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td>

最后,在表单的底部,我们将想要更新新邮件路径,以便在他们想要创建新邮件时将用户带到相应的嵌入式路径。

1[label ~/sharkapp/app/views/posts/index.html.erb]
2. . . 
3<%= link_to 'New Post', new_shark_post_path(@shark) %>

完成的文件将看起来像这样:

 1[label ~/sharkapp/app/views/posts/index.html.erb]
 2<p id="notice"><%= notice %></p>
 3
 4<h1>Posts</h1>
 5
 6<table>
 7  <thead>
 8    <tr>
 9      <th>Body</th>
10      <th>Shark</th>
11      <th colspan="3"></th>
12    </tr>
13  </thead>
14
15  <tbody>
16    <% @posts.each do |post| %>
17      <tr>
18        <td><%= post.body %></td>
19        <td><%= post.shark.name %></td>
20        <td><%= link_to 'Show Shark', [@shark] %></td>
21        <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
22        <td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td>
23      </tr>
24    <% end %>
25  </tbody>
26</table>
27
28<br>
29
30<%= link_to 'New Post', new_shark_post_path(@shark) %>

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

我们将发布的其他观点的其他编辑不会那么多,因为我们的其他观点使用我们已经编辑的形式部分,但是,我们将希望更新其他帖子模板中的link_to参考,以反映我们对我们的形式部分所做的更改。

打开app/views/posts/new.html.erb:

1nano app/views/posts/new.html.erb

更新文件底部的 link_to 引用,以使用 shark_posts_path(@shark) 帮助:

1[label ~/sharkapp/app/views/posts/new.html.erb]
2. . . 
3<%= link_to 'Back', shark_posts_path(@shark) %>

保存并关闭文件,当您完成执行此更改。

接下来,打开编辑模板:

1nano app/views/posts/edit.html.erb

除了返回路径外,我们还会更新显示,以反映我们嵌入的资源。

1[label ~/sharkapp/app/views/posts/edit.html.erb]
2. . . 
3<%= link_to 'Show', [@shark, @post] %> |
4<%= link_to 'Back', shark_posts_path(@shark) %>

保存并关闭文件。

接下来,打开表演模板:

1nano app/views/posts/show.html.erb

对文件底部的编辑返回路径进行以下编辑:

1[label ~/sharkapp/app/views/posts/edit.html.erb]
2. . .
3<%= link_to 'Edit', edit_shark_post_path(@shark, @post) %> |
4<%= link_to 'Back', shark_posts_path(@shark) %>

保存并关闭文件,当你完成。

作为最后一步,我们将更新我们的鲨鱼的显示视图,以便对个别鲨鱼的帖子可见。

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

我们的编辑将包括将帖子部分添加到表单和文件底部的添加帖子链接。

在给定鲨鱼的事实下面,我们将添加一个新的部分,它在与这个鲨鱼相关的帖子集中的每个实例中重复,输出每个帖子的身体

在表单的事实部分下方,并在文件底部的重定向上方添加下面的代码:

 1[label ~/sharkapp/app/views/sharks/show.html.erb]
 2. . .
 3<p>
 4  <strong>Facts:</strong>
 5  <%= @shark.facts %>
 6</p>
 7
 8<h2>Posts</h2>
 9<% for post in @shark.posts %>
10    <ul>
11      <li><%= post.body %></li>
12  </ul>
13<% end %>
14
15<%= link_to 'Edit', edit_shark_path(@shark) %> |
16. . .

接下来,添加一个新的重定向,以允许用户为这个特定的鲨鱼添加一个新的帖子:

1[label ~/sharkapp/app/views/sharks/show.html.erb]
2. . .
3<%= link_to 'Edit', edit_shark_path(@shark) %> |
4<%= link_to 'Add Post', shark_posts_path(@shark) %> |
5<%= link_to 'Back', sharks_path %>

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

您现在已经对应用程序的模型、控制器和视图进行了更改,以确保帖子始终与特定鲨鱼相关联,作为最后一步,我们可以将一些验证添加到我们的邮件模型中,以确保存储到数据库的数据的一致性。

步骤5 – 添加验证和测试应用程序

步骤 5 of How To Build a Ruby on Rails Application,你添加了验证到你的 Shark 模型,以确保将数据存储到 sharks 数据库中的统一性和一致性。我们现在将采取类似的步骤,以确保对 post 数据库的保证。

打开您的Post模型定义的文件:

1nano app/models/post.rb

在这里,我们要确保帖子不是空的,并且它们不会重复其他用户可能发布的内容。

1[label ~/sharkapp/app/models/post.rb]
2class Post < ApplicationRecord
3  belongs_to :shark
4  validates :body, presence: true, uniqueness: true
5end

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

有了这个最后的更改,您已经准备好运行迁移并测试应用程序。

首先,运行您的迁移:

1rails db:migrate

接下来,启动您的服务器. 如果您在本地工作,您可以通过运行:

1rails s

如果您正在开发服务器上工作,请运行以下命令:

1rails s --binding=your_server_ip

点击http://localhost:3000http://your_server_ip:3000导航到应用程序的根。

预先要求的 Rails 项目教程向您介绍了添加和编辑一个 Great White 鲨鱼条目. 如果您没有添加任何其他鲨鱼,应用程序登陆页面将看起来像这样:

Shark App Landing Page

点击 显示 旁边的名称** 大白 ** 这会带你到这个鲨鱼的显示视图。你会看到鲨鱼的名字及其事实,以及一个没有内容的** 帖子** 标题。让我们添加一个帖子来填充表单的这个部分。

点击添加帖子帖子标题下方,这将带您到帖子索引视图中,您将有机会选择新帖子:

Post Index View

由于您在 步骤 6中的身份验证机制(https://andsky.com/tech/tutorials/how-to-build-a-ruby-on-rails-application),您可能会被要求使用您在该步骤中创建的用户名和密码进行身份验证,取决于您是否创建了一个新会话。

点击 新帖子 ,将带你到你的帖子模板:

New Post

身体字段中,键入这些鲨鱼是可怕的!

New Shark Post

点击创建帖子你将被重定向到索引视图的所有帖子,属于这个鲨鱼:

Post Success

随着我们的邮件资源工作,我们现在可以测试我们的数据验证,以确保只有所需的数据存储到数据库中。

索引视图中,点击新邮件。在新表单的身体字段中,尝试再次输入这些鲨鱼是可怕的!:

Repeat Shark Post

点击创建帖子你会看到以下错误:

Unique Post Error

点击返回返回主页。

要测试我们的其他验证,请再次点击 新帖子 留下帖子空,然后点击** 创建帖子** 您将看到以下错误:

Blank Post Error

随着您的集成资源和验证工作正常,您现在有一个工作 Rails 应用程序,您可以将其用作进一步开发的起点。

结论

如果您想了解更多关于路由和嵌入资源的信息,则 Rails 文档是开始的好地方。

有关将前端框架与应用程序集成的更多信息,请参阅 如何使用 React Frontend 设置 Ruby on Rails 项目

Published At
Categories with 技术
comments powered by Disqus