Ruby on Rails - 视图
Rails 视图是一个 ERb 程序,它通过可相互访问的变量与控制器共享数据。
如果您查看库应用程序的 app/views 目录,您将看到我们创建的每个控制器都有一个子目录:book。当使用生成脚本创建同名控制器时,会自动创建这些子目录。
Rails 让您知道您需要为每个新方法创建视图文件。您在控制器中定义的每个方法都需要有一个相应的 erb 文件,其名称与该方法相同,以显示该方法正在收集的数据。
因此,让我们为 book_controller.rb 中定义的所有方法创建视图文件。在执行这些视图时,同时检查这些操作是否适用于数据库。
为列表方法创建视图文件
使用您最喜欢的文本编辑器创建一个名为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。
现在,尝试刷新浏览器,您应该会看到以下屏幕,因为我们的图书馆中没有任何书籍。
为新方法创建视图文件
到目前为止,我们的图书馆中没有任何书籍。我们必须在系统中创建几本书。因此,让我们设计一个与 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,创建一个从数组构建的 HTML 选择菜单,例如 @books 菜单。有五个参数,如下所示 −
:book −您正在操作的对象。在本例中,它是一本书对象。
:subject_id − 保存书籍时填充的字段。
@books − 您正在处理的数组。
:id − 存储在数据库中的值。就 HTML 而言,这是 <option> 标签的值参数。
:name − 用户在下拉菜单中看到的输出。这是 <option> 标签之间的值。
接下来使用的是 submit_tag,它输出一个用于提交表单的 <input> 按钮。最后,还有 end 方法,它简单地转换为 </form>。
转到浏览器并访问 http://localhost:3000/book/new。 这将为您提供以下屏幕。
在此表单中输入一些数据,然后单击"创建"按钮。在这里,我已将以下详细信息添加到字段中 −
Title: Advance Physics Price: 390 Subject: Physics Description: This is test to create new book
单击 Create 按钮时,它将调用 create 方法,该方法不需要任何视图,因为此方法使用 list 或 new 方法来查看结果。因此,单击"Create"按钮时,数据应成功提交并将您重定向到列表页面,其中现在您有一个列出的项目,如下所示 −
如果单击链接,您应该会看到另一个"缺少模板"错误,因为您尚未为 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 变量提取主题的名称值。如果单击任何列出的记录,它将显示以下屏幕。
为 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>
现在,尝试使用 http://localhost:3000/book/list 浏览书籍。它将为您提供所有书籍的列表以及 编辑 选项。单击"编辑"选项后,您将看到下一个屏幕,如下所示 −
现在,您可以编辑此信息,然后单击 保存更改 按钮。这将导致调用控制器文件中可用的 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 确认框,询问您是否确实要执行该操作。如果用户单击"确定",则操作将继续,并删除该项目。
现在,尝试使用 http://localhost:3000/book/list 浏览书籍。它将为您提供所有书籍的列表以及 编辑 和 删除 选项,如下所示 −
现在使用删除选项,您可以删除任何列出的记录。
为 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>
现在尝试使用 http://localhost:3000/book/list 浏览书籍。它将显示所有带链接的主题,以便您可以浏览与该主题相关的所有书籍。
下一步是什么?
希望现在您对 Rails 的所有操作都感到满意。
下一章将介绍如何使用 Layouts 以更好的方式放置数据。我们将向您展示如何在 Rails 应用程序中使用 CSS。