Ruby on Rails - 视图



Rails 视图是一个 ERb 程序,它通过互相访问的变量与控制器共享数据。

如果您查看 library 应用程序的 app/views 目录,您会看到为我们创建的每个控制器都有一个子目录:book。每次使用 generate 脚本创建同名控制器时,都会自动创建这些子目录。

Rails 会让您知道您需要为每个新方法创建视图文件。您在控制器中定义的每个方法都需要有一个与方法同名的相应 **erb** 文件,以显示该方法正在收集的数据。

因此,让我们为我们在 book_controller.rb 中定义的所有方法创建视图文件。执行这些视图时,同时检查这些操作是否适用于数据库。

为 list 方法创建视图文件

使用您喜欢的文本编辑器创建一个名为 **list.html.erb** 的文件,并将其保存到 app/views/book。创建并保存文件后,刷新您的网页浏览器。您应该看到一个空白页面;如果看不到,请检查文件的拼写,确保它与控制器的名称完全相同。

现在,显示实际内容。让我们将以下代码放入 list.html.erb 中。

<% if @books.blank? %>
<p>There are not any books currently in the system.</p>
<% else %>
<p>These are the current books in our system</p>

<ul id = "books">
   <% @books.each do |c| %>
   <li><%= link_to c.title, {:action => 'show', :id => c.id} -%></li>
   <% end %>
</ul>

<% end %>
<p><%= link_to "Add new Book", {:action => 'new' }%></p>

要执行的代码是检查 @books 数组中是否包含任何对象。如果数组为空,**.blank?** 方法返回 true,如果数组包含任何对象,则返回 false。此 @books 对象是在控制器中 list 方法内创建的。

<%= %> 标记之间的代码是 **link_to** 方法调用。link_to 的第一个参数是 <a> 标记之间要显示的文本。第二个参数是单击链接时调用的操作。在本例中,它是 show 方法。最后一个参数是通过 params 对象传递的图书 ID。

现在,尝试刷新浏览器,您应该会看到以下屏幕,因为我们的图书馆中没有任何图书。

No Book Message

为 new 方法创建视图文件

到目前为止,我们的图书馆中没有任何图书。我们必须在系统中创建一些图书。因此,让我们设计一个与 book_controller.rb 中定义的 **new** 方法对应的视图。

使用您喜欢的文本编辑器创建一个名为 new.html.erb 的文件,并将其保存到 app/views/book。将以下代码添加到 new.html.erb 文件。

<h1>Add new book</h1>

<%= form_tag :action => 'create' do %>
<p><label for = "book_title">Title</label>:

<%= text_field 'books', 'title' %></p>
<p><label for = "book_price">Price</label>:

<%= text_field 'books', 'price' %></p>
<p><label for = "book_subject_id">Subject</label>:

<%= collection_select(:books, :subject_id, @subjects, :id, :name, prompt: true) %></p>
<p><label for = "book_description">Description</label><br/>

<%= text_area 'books', 'description' %></p>
<%= submit_tag "Create" %>

<% end -%>
<%= link_to 'Back', {:action => 'list'} %>

这里的 **form_tag** 方法使用提供给它的所有信息将 Ruby 代码解释为常规 HTML <form> 标记。例如,此标记输出以下 HTML:

<form action = "/book/create" method = "post">

下一个方法是 **text_field**,它输出一个 <input> 文本字段。text_field 的参数是对象和字段名称。在本例中,对象是 *book*,名称是 *title*。

Rails 方法 **collection_select** 创建一个从数组(例如 @books 数组)构建的 HTML 选择菜单。共有五个参数,如下所示:

  • **:book** - 您正在操作的对象。在本例中,它是一个 book 对象。

  • **:subject_id** - 保存图书时填充的字段。

  • **@books** - 您正在使用的数组。

  • **:id** - 存储在数据库中的值。就 HTML 而言,这是 <option> 标记的 value 参数。

  • **:name** - 用户在下拉菜单中看到的输出。这是 <option> 标记之间的值。

接下来使用的是 **submit_tag**,它输出一个提交表单的 <input> 按钮。最后,有一个 **end** 方法,它简单地转换为 </form>。

转到您的浏览器并访问 **https://127.0.0.1:3000/book/new。** 这将为您提供以下屏幕。

New Book

在此表单中输入一些数据,然后单击“创建”按钮。我在字段中添加了以下详细信息:

Title: Advance Physics
Price: 390
Subject: Physics
Description: This is test to create new book

单击“创建”按钮时,它将调用 **create** 方法,该方法不需要任何视图,因为此方法使用 **list** 或 **new** 方法来查看结果。因此,当您单击“创建”按钮时,数据应成功提交并重定向到列表页面,其中您现在列出了单个项目,如下所示:

Create Book

如果您单击链接,您应该会看到另一个“模板丢失”错误,因为您尚未为 show 方法创建模板文件。

为 show 方法创建视图文件

此方法将显示图书馆中任何图书的完整详细信息。在 app/views/book 下创建一个 show.html.erb 文件,并使用以下代码填充它:

<h1><%= @book.title %></h1>

<p>
   <strong>Price: </strong> $<%= @book.price %><br />
   <strong>Subject :</strong> <%= @book.subject.name %><br />
   <strong>Created Date:</strong> <%= @book.created_at %><br />
</p>

<p><%= @book.description %></p>

<hr />

<%= link_to 'Back', {:action => 'list'} %>

这是您第一次充分利用关联,关联使您可以轻松地从相关对象中提取数据。

使用的格式是 **@variable.relatedObject.column**。在本例中,您可以使用 **belongs_to** 关联通过 @book 变量提取主题的名称值。如果单击任何列出的记录,它将显示以下屏幕。

Show Book

为 edit 方法创建视图文件

创建一个名为 edit.html.erb 的新文件,并将其保存到 app/views/book。使用以下代码填充它:

<h1>Edit Book Detail</h1>

<%= form_for @book, :url =>{:action => "update", :id =>@book} do |f| %>

<p>Title: <%= f.text_field 'title' %></p>
<p>Price: <%= f.text_field  'price' %></p>
<p>Subject: <%= f.collection_select :subject_id, Subject.all, :id, :name %></p>
<p>Description<br/>

<%= f.text_area 'description' %></p>
<%= f.submit "Save changes" %>
<% end %>

<%= link_to 'Back', {:action => 'list' } %>

此代码与 **new** 方法非常相似,只是要更新的操作而不是创建和定义 ID。

在这种情况下,我们为表单操作使用了 **form_for** 标记。它的性能将优于 **form_tag**。原因是它将轻松地与模型进行交互。因此,每当您需要模型和表单字段之间的交互时,最好使用 form_for 标记。

此时,我们需要修改 **list 方法** 的视图文件。转到 <li></li> 元素并将其修改为如下所示:

<li>
   <%= link_to c.title, {:action => "show", :id => c.id} -%>
   <b> <%= link_to 'Edit', {:action => "edit",
   :id => c.id} %></b>
</li>

现在,尝试使用 **https://127.0.0.1:3000/book/list** 浏览图书。它将为您提供所有图书的列表以及 **编辑** 选项。当您单击“编辑”选项时,您将看到下一个屏幕,如下所示:

Edit Book

现在,编辑此信息,然后单击“保存更改”按钮。这将导致调用控制器文件中可用的 **update** 方法,并且它将更新所有更改的属性。请注意,**update** 方法不需要任何视图文件,因为它使用 **show** 或 **edit** 方法来显示其结果。

为 delete 方法创建视图文件

使用 Ruby on Rails 从数据库中删除信息几乎太容易了。您无需为 delete 方法编写任何视图代码,因为此方法使用 **list** 方法来显示结果。因此,让我们再次修改 list.html.erb 并添加一个删除链接。

转到 <li></li> 元素并将其修改为如下所示:

<li>
   <%= link_to c.title, {:action => 'show', :id => c.id} -%>
   <b> <%= link_to 'Edit', {:action => 'edit', :id => c.id} %></b>
   <b> <%= link_to "Delete", {:action => 'delete', :id => c.id},
      :confirm => "Are you sure you want to delete this item?" %></b>
</li>

**:confirm** 参数会显示一个 JavaScript 确认框,询问您是否真的要执行此操作。如果用户单击“确定”,则操作将继续进行,并且项目将被删除。

现在,尝试使用 **https://127.0.0.1:3000/book/list** 浏览图书。它将为您提供所有图书的列表以及 **编辑** 和 **删除** 选项,如下所示:

Delete Book

现在,使用“删除”选项,您可以删除任何列出的记录。

为 show_subjects 方法创建视图文件

在 app/views/book 目录中创建一个新文件 show_subjects.html.erb,并向其中添加以下代码:

<h1><%= @subject.name -%></h1>

<ul>
   <% @subject.books.each do |c| %>
   <li><%= link_to c.title, :action => "show", :id => c.id -%></li>
   <% end %>
</ul>

您正在通过迭代单个主题的许多图书列表来利用关联。

现在修改 show.html.erb 的“主题:”行,以便主题列表显示一个链接。

<strong>Subject: </strong> <%= link_to @book.subject.name,
:action => "show_subjects", :id => @book.subject.id %><br />

这将在索引页面上输出主题列表,以便用户可以直接访问它们。

修改 **list.html.erb** 以将以下内容添加到文件顶部:

<ul id = "subjects">
   <% Subject.find(:all).each do |c| %>
   <li><%= link_to c.name, :action => "show_subjects", :id => c.id %></li>
   <% end %>
</ul>

现在尝试使用 https://127.0.0.1:3000/book/list 浏览图书。它将显示所有带有链接的主题,以便您可以浏览与该主题相关的全部图书。

List Subjects

接下来是什么?

希望您现在对 Rails 的所有操作都感到满意。

下一章将解释如何使用 **布局** 以更好的方式显示您的数据。我们将向您展示如何在 Rails 应用程序中使用 CSS。

广告