noAh's Steps on Rails or sth. Else.

Whatever, keep going ahead.
  首页  :: 新随笔  :: 管理

AWDwR depot例程 store页面

Posted on 2008-10-30 14:07  noAh....  阅读(351)  评论(0)    收藏  举报

  我们已经给卖家创建了管理products的页面,现在创建第二个控制器,为买家创建一个与卖家的交互控制器,称为store。

  >ruby script/generate controller store index

D:\rails\depot>ruby script/generate controller store index
exists app/controllers/
exists app/helpers/
create app/views/store
exists test/functional/
create app/controllers/store_controller.rb
create test/functional/store_controller_test.rb
create app/helpers/store_helper.rb
create app/views/store/index.html.erb

D:\rails\depot>

  因为rails没有指定一个action来调用控制器的话,rails会自动调用index()方法。

  我们重启server,进入http://localhost:3000/store,你会看到如下页面。

 store.index

  这个自动生成页面意味着一切还正常。我们先设计一个简单的页面,显示数据库中可以销售的货物。

  先去修改store_controller.rb文件中的index方法。

app/controllers/store_controller.rb

class StoreController < ApplicationController
def index
@products
= Product.find_products_for_sale
end

end

   很显然这还远远不够。我们在product.rb文件中去定义find_products_for_sale方法。下面的代码就是该方法的实现,其中使用了rails提供的find方法, :all参数代表我们希望去除符合指定条件的所有记录,并且按名称对货物排序。

app/models/product.rb

class Product < ActiveRecord::base
def sef.find_products_for_sale
find(:all, :order
=> "title")
end

#validation stuff

end

  find()方法会返回一个数组,其中的每个元素是一个Product对象,分别从数据库返回一条记录。find_products_for_sale方法直接把这个数组返回给控制器。我们在find_products_for_sale方法前面加上self,这样我们可以直接通过Product.find_products_for_sale来调用它。
  现在我们去编辑视图模板。
app/views/store/index.html.erb
<h1>Your Pragmatic Catalog</h1>

<% for product in @products -%>
<div class="entry">
<%= image_tag(product.image_url) %>
<h3><%=h product.title %></h3>
<%= product.description %>
<span class="price"><%= product.price %></span>
</div>
<% end %>

  按刷新按钮,我们就看到了下图类似的页面。这个页面的美观性不做评价,因为我们没有添加任何css样式表进去。
 store/index
 
  让我们为了更为美观的页面去添加一个页面布局。布局就是一个模板。我们可以将货物信息填充进去,可以把“购物车”,“结账”的页面也放进同样的布局。
  如果在app\views\layouts目录中创建了一个与某控制器同名的模板文件,那么该控制器所渲染的视图在默认状态下会使用此布局模板。我们的控制器叫store,我们去创建一个叫store.html.erb的模板。
app/views/layouts/store.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<html>
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "depot", :media => "all" %>
</head>
<body id="store">
<div id="banner">
<%= image_tag("logo.png") %>
<%= @page_title || "Pragmatic Bookshelf" %>
</div>
<div id="columns">
<div id="side">
<a href="http://www.">Home</a><br />
<a href="http://www./faq">Questions</a><br />
<a href="http://www./news">News</a><br />
<a href="http://www./contact">Contact</a><br />
</div>
<div id="main">
<%= yield :layout %>
</div>
</div>
</body>
</html>

  这个模板的代码除了一般的html代码,还包涵了三个rails特有的东西。第6行中使用了一个Rails辅助方法,用于生成指向depot.css样式表的<link>标签。第11行我们将页面的开头设置为@page_title变量的值。在第21行,我们调用yield方法并传入:layout时,Rails会自动在这里插入页面的内容!也就是在真实生成的页面中,index.html.erb占据了页面的右下部分。
layouts for store
 
  我们对表示价格的数字格式化一下。在index模板中将
<span class="price"><%= product.price %></span>
  改成
Code
  最后我们添加一个“add to cart”的按钮链接,使用button_to()方法。
<%= button_to "Add to Cart", :action => :add_to_cart %>

  现在app/views/store/index.html.erb
<h1>Your Pragmatic Catalog</h1>
<% for product in @products -%>
<div class="entry">
<%= image_tag(product.image_url) %>
<h3><%=h product.title %></h3>
<%= product.description %>
<span class="price"><%= number_to_currency(product.price) %></span>
<%= button_to "Add to Cart", :action => :add_to_cart, :id => product %>
</div>
<% end %>

  我们再在depot.css中添加上几行,避免“add to cart”按钮另起一行。
#store .entry form, #store .entry form div {
display: inline;
}

  现在再看看我们的页面。
 add to cart