Ruby on Rails 2.1 - 视图


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

如果您查看库应用程序的 app/views 目录,您将看到我们创建的每个控制器都有一个子目录:book。当使用生成脚本创建同名控制器时,每个子目录都会自动创建。

现在,假设您的 Web 服务器已启动并正在运行,请在浏览器的地址框中提供以下输入 -

http://localhost:3000/book/list

您会收到以下错误消息,因为您尚未为控制器中定义的任何方法定义任何视图文件。

缺少模板

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

因此,让我们为 book_controller.rb 中定义的所有方法创建视图文件。

为列表方法创建视图文件

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

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

<% 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数组中是否有任何对象。.空白?如果数组为空,则方法返回 true;如果数组包含任何对象,则返回 false。这个 @books 对象是在控制器的 list 方法中创建的。

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

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

无书留言

为新方法创建视图文件

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

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

<h1>Add new book</h1>

<% form_tag :action => 'create'  do %>

<p><label for="book_title">Title
</label>:

<%= text_field 'book', 'title' %></p>

<p><label for="book_price">Price</label>:

<%= text_field 'book', 'price' %></p>

<p><label for="book_subject">Subject</label>:

<%= collection_select(:book,:subject_id,@subjects,:id,:name) %></p>

<p><label for="book_description">Description</label><br/>

<%= text_area 'book', 'description' %></p>

<%= submit_tag "Create" %>

<% end  %>

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

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

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

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

名为collection_select的 Rails 方法创建一个从数组构建的 HTML 选择菜单,例如 @books 菜单。有五个参数,如下 -

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

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

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

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

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

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

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

新书

在此表单中输入一些数据,然后单击“创建”按钮。这将导致调用create方法,该方法不需要任何视图,因为该方法使用listnew方法来查看结果。当您单击“创建”按钮时,数据应成功提交并将您重定向到列表页面,其中现在列出了一个项目,如下所示 -

创建书籍

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

为 show 方法创建视图文件

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

<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.latedObject.column在这种情况下,您可以使用belongs_to关联通过@book 变量拉取主题的名称值。如果您单击任何列出的记录,它将显示以下屏幕。

展示书

为编辑方法创建视图文件

创建一个名为 edit.rhtml 的新文件并将其保存在 app/views/book 中。使用以下代码填充它 -

<h1>Edit Book Detail</h1>

<%= start_form_tag :action => 'update', :id => @book do %>

<p><label for="book_title">Title</label>:

   <%= text_field 'book', 'title' %></p>

<p><label for="book_price">Price</label>:

   <%= text_field 'book', 'price' %></p>

<p><label for="book_subject">Subject</label>:

   <%= collection_select(:book, :subject_id,
   @subjects, :id, :name) %></p>

<p><label for="book_description">Description</label><br/>

   <%= text_area 'book', 'description' %></p>

<%= submit_tag "Save changes" %>

<% end %>

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

此代码与新方法非常相似,不同之处在于要更新操作而不是创建和定义 id。

此时,我们需要对列表方法的视图文件进行一些修改。转到 <li></li> 元素并修改它,使其如下所示 -

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

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

编辑书籍

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

为删除方法创建视图文件

使用 Ruby on Rails 从数据库中删除信息几乎太容易了。你不需要为delete方法编写任何查看代码,因为该方法使用列表方法来显示结果。因此,我们再次修改list.rhtml并添加删除链接。

转到 <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 确认框,询问您是否确实要执行该操作。如果用户单击“确定”,操作将继续,并且该项目将被删除。

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

删除书籍

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

为 show_subjects 方法创建视图文件

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

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

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

现在,修改 show.rhtml 的主题行,以便主题列表显示一个链接。

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

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

修改list.rhtml以在文件顶部添加以下内容 -

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

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

列出主题

下一步是什么?

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

下一章将介绍如何使用布局以更好的方式放置数据。我们还将向您展示如何在 Rails 应用程序中使用 CSS。