The Last Day Of Summer

.NET技术 C# ASP.net ActiveReport SICP 代码生成 报表应用 RDLC
posts - 305, comments - 1973, trackbacks - 78, articles - 3
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

前面的内容里,我们演示了怎样构建一个商品的列表,这次,我们在前面内容的基础上,构建一个简单的购物车。

 

1.         首先我们要来创建一个保存客户购物信息的表:

数据库脚本:

drop table if exists line_items;

create table line_items (

id int not null auto_increment,

product_id int not null,

quantity int not null default 0,

unit_price decimal(10,2) not null,

constraint fk_items_product foreign key (product_id) references products(id),

primary key (id)

);

之后在PhpMyAdmin中创建表,然后使用Rails命令行创建line_item表对应的类:

depot> ruby script/generate model LineItem

(创建的详细步骤可以参考前面的几篇随笔)

 

2.       LineItemProduct创建主从关系:

打开\rails_apps\depot\app\models目录下的line_item.rb文件,修改文件内容为:

class LineItem < ActiveRecord::Base

belongs_to :product

end

可以看到belongs_to :product这句给LineItemProduct创建了主从关系。

 

3.       现在,我们可以添加ruby代码了。

首先是rails_apps\depot\app\controllers目录下的store_controller.rb文件,给其中添加方法:

private

def find_cart

session[:cart] ||= Cart.new

end

实际上,在上篇随笔中,在rails_apps\depot\app\views\store目录下的index.rhtml文件中,我们可以看到这样的代码:

<%= link_to 'Add to Cart',

{:action => 'add_to_cart', :id => product },

:class => 'addtocart' %>

    这句代码的就是给Add to Cart链接指定它的Action,相应的,我们要在store_controller.rb中添加add_to_cart方法

def add_to_cart

product = Product.find(params[:id])

@cart = find_cart

@cart.add_product(product)

redirect_to(:action => 'display_cart')

end

上面的代码中,首先调用了Productfind方法,然后是store_controllerfind_cart方法,接下来调用Cartadd_product方法,然后在重定向页面,Actiondisplay_cart

好了,下面我们来编写这些方法中要用到的代码。

 

l         创建Cart类,我们在app/models目录下,创建cart.rb文件,代码如下:

class Cart

attr_reader :items

attr_reader :total_price

def initialize

@items = []

@total_price = 0.0

end

def add_product(product) <<

@items << LineItem.for_product(product)

@total_price += product.price

end

end

l         LineItem添加一个方法for_product,代码如下:

class LineItem < ActiveRecord::Base

belongs_to :product

def self.for_product(product) self.new

item = self.new

item.quantity = 1

item.product = product

item.unit_price = product.price

item

end

end

l         store_controller.rb文件中添加方法display_cart,代码:

def display_cart

@cart = find_cart

@items = @cart.items

end

l         我们再来创建一个显示Cart的页面。

rails_apps\depot\app\views\store目录下,新建,一个display_cart.rhtml文件,修改内容:

<h1>Display Cart</h1>

<p>

Your cart contains <%= @items.size %> items.

</p>

l         这时候,如果我们点击Add to Cart链接的话,会出现一个error页面,这是因为我们还没有定义session。这一步我们需要修改rails_apps\depot\app\controllers目录下的application.rb文件,使其内容为:

# Filters added to this controller apply to all controllers in the application.

# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base

  # Pick a unique cookie name to distinguish our session data from others'

  #session:session_key => '_depot_session_id'

model :cart

model :line_item

end

l         到此,再点击点击Add to Cart链接,应该会出现一个正常的页面了。

 

4.       现在,虽然我们已经有了一个可以运行的页面,但是你会发现,如果你多次添加同一件商品,在display_cart页面上会一条一条显示。我们来完善一下这些代码,修改add_product方法:

def add_product(product)

item = @items.find {|i| i.product_id == product.id}

if item

item.quantity += 1

else

item = LineItem.for_product(product)

@items << item

end

@total_price += product.price

end

最后再美化下display_cart页面:

<html>

    <head>

 

    <%= stylesheet_link_tag "scaffold", "depot", "admin", :media => "all" %>

    </head>

    <div id="cartmenu">

            <ul>

                    <li><%= link_to 'Continue shopping', :action => "index" %></li>

                    <li><%= link_to 'Empty cart', :action => "empty_cart" %></li>

                    <li><%= link_to 'Checkout', :action => "checkout" %></li>

            </ul>

    </div>

    <table cellpadding="10" cellspacing="0">

            <tr class="carttitle">

                    <td rowspan="2">Qty</td>

                    <td rowspan="2">Description</td>

                    <td colspan="2">Price</td>

            </tr>

            <tr class="carttitle">

                    <td>Each</td>

                    <td>Total</td>

            </tr>

            <%

            for item in @items

                    product = item.product

            -%>

                    <tr>

                            <td><%= item.quantity %></td>

                            <td><%= h(product.title) %></td>

                            <td align="right"><%= item.unit_price %></td>

                            <td align="right"><%= item.unit_price * item.quantity %></td>

                    </tr>

            <% end %>

            <tr>

                    <td colspan="3" align="right"><strong>Total:</strong></td>

                    <td id="totalcell"><%= @cart.total_price %></td>

            </tr>

    </table>

</html>

 

OK,大功告成了,来看看最后的效果:
 

Feedback

#1楼   回复  引用  查看    

2007-07-09 21:30 by YAO.NET(三千)℡      
学习.

#2楼   回复  引用    

2007-10-10 13:50 by CDmyname[未注册用户]
这句代码的就是给Add to Cart链接指定它的Action,相应的,我们要在store_controller.rb中添加add_to_cart方法

#上面的你介绍的很好,也很容易让人明白,可是下面的有点搞不清楚了,如果有时间的话介绍下下面的,比如:
def add_to_cart #定义add_to_cart 方法


#在Product里面获取具体ID的product
product = Product.find(params[:id])
@cart = find_cart

@cart.add_product(product)

redirect_to(:action => 'display_cart')

end

等等,毕竟资料少,做下就做最好!我们初学者一定会对你感激万分的

#3楼[楼主]   回复  引用  查看    

2007-10-10 18:28 by Cure      
@CDmyname
谢谢你指出问题,后面我会注意,不仅仅是复述书上的东西,能有自己的东西写进来。

因为我也是刚刚开始学习rails,也是看着书,一点点抄的,当作是学习笔记,对很多地方还都不太明白,所以不敢贸然写自己还不确定的东西。

我干脆把我看的电子书上传,大家都好交流:)

#4楼   回复  引用    

2007-10-13 10:53 by CDmyname[未注册用户]
呵呵,你谦虚了,你做的很好,有机会和你一起搞;
我们也正在做一个用户积分兑换系统,和这个差不多,希望能和你交流
我的MSN : congde@hotmail.com
email : jiangcongde@yahoo.com.cn
or j.cd@163.com

#5楼   回复  引用    

2007-11-19 16:47 by linzy[未注册用户]
今天小小郁闷了一下,跟着你这篇和英文原版对照着做例子,但老说add_to_cart这个action找不到,搞了半天才发现这个方法写在那个私有的find_cart方法下面,原来ruby会默认private下面的方法都为私有的,我学ruby才刚开始,被这小小郁闷一下。
特写一下,万一还有有新人跟我一样

#6楼[楼主]   回复  引用  查看    

2007-11-19 18:31 by Cure      
@linzy
谢谢,我在写随笔时,有时也很随意,有些不清楚或省略的地方,还请大家齐力补充完善。

#7楼   回复  引用    

2007-12-13 16:34 by yangsx[未注册用户]
能给我写一个完整的rails发送e-mail的简单应用吗?能实现的.

#8楼[楼主]   回复  引用  查看    

2007-12-14 00:25 by Cure      
@yangsx
嗯,看到书里有这方面的例子,但是自己还没学到那里,只好先等等了:)

#9楼   回复  引用    

2007-12-14 09:10 by yangsx[未注册用户]
我也正在学ROR,随时保持交流.

#10楼   回复  引用    

2008-01-19 14:47 by be0701[未注册用户]
4. 现在,虽然我们已经有了一个可以运行的页面,但是你会发现,如果你多次添加同一件商品,在display_cart页面上会一条一条显示。我们来完善一下这些代码,修改add_product方法:

def add_product(product)

item = @items.find {|i| i.product_id == product.id}

if item

item.quantity += 1

else

item = LineItem.for_product(product)

@items << item

end

@total_price += product.price

end


请问这是Cart类中的add_product(product)方法吗???????救救!

#11楼   回复  引用    

2008-01-19 15:27 by be0701[未注册用户]
做完以上操作 检查了两次 还是 在点击 Addto Cart 的时候跳到一个报错页面 页面提示:Unknown action
No action responded to add_to_cart

具体是什么问题呢??? 高手指点

#12楼   回复  引用    

2008-01-19 15:40 by be0701[未注册用户]
再检查了一下 :查处问题了

这时候,如果我们点击Add to Cart链接的话,会出现一个error页面,这是因为我们还没有定义session。这一步我们需要修改rails_apps\depot\app\controllers目录下的application.rb文件,使其内容为:

# Filters added to this controller apply to all controllers in the application.

# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base

# Pick a unique cookie name to distinguish our session data from others'

#session:session_key => '_depot_session_id'

model :cart

model :line_item

end

这句“#session:session_key => '_depot_session_id'
应该改成:session:session_key => '_depot_session_id'
去掉”#“

#13楼   回复  引用    

2008-03-10 22:12 by 牛仔[未注册用户]
我点击 add to cart 是为什么总是出错,提示是:undefined method `quantity' for 53:Fixnum。item.quantity: item.product:等都会出现这种错误。

#14楼   回复  引用    

2008-04-06 23:43 by jun1st[未注册用户]
Cart类的代码有误,呵呵
def add_product(product) 没有最后的<<

有个问题啊,在Rails2.0中,好像redirect不到display_cart这个页面上去啊,
一点add_to_cart就显示一个只有edit和back的linkbutton的页面

楼主知道怎么回事吗?

#15楼   回复  引用    

2008-06-19 12:21 by 六翼[未注册用户]
也是出现
NoMethodError in StoreController#add_to_cart
的问题,是说“add_to_cart”这个Controller里出现了不明的方法?

又看下面的报错信息:
#{RAILS_ROOT}/app/models/cart.rb:9:in `add_product'
#{RAILS_ROOT}/app/controllers/store_controller.rb:9:in `add_to_cart'

cart.rb的第9行是这个:@items << LineItem.for_product(product)
store_controller.rb的第9行是这个:@cart.add_product(product)

看起来也没什么问题吧?(囫囵吞枣地跟到这步,还真是很晕,哪一块是干嘛的也不太懂@_@)

#16楼   回复  引用    

2008-06-24 19:04 by lee_chan[未注册用户]
我确信是按照步骤一步步做的,可是根本无法运行,老是出现下面的提示
Status: 500 Internal Server Error Content-Type: text/html

#17楼   回复  引用    

2008-06-27 14:54 by geniushjs[未注册用户]
楼上的,我也是。。。
你解决了吗?
联系我QQ276810220
@lee_chan

#18楼   回复  引用    

2008-07-28 15:44 by 太平洋[未注册用户]
为什么一数据库的SESSION存储机制就会出现
Status: 500 Internal Server Error Content-Type: text/html

#19楼   回复  引用    

2008-07-28 15:45 by 太平洋[未注册用户]
为什么一激活数据库的SESSION存储机制就会出现
Status: 500 Internal Server Error Content-Type: text/html
大家有遇到吗??我SESSIONS表也建了啊!!!

#20楼   回复  引用    

2008-07-28 15:55 by 太平洋[未注册用户]
解决了,看日志发现了问题,以下是SESSIONS的表结构:
DROP TABLE IF EXISTS `sessions`;
CREATE TABLE `sessions` (
`session_id` varchar(255) DEFAULT NULL,
`data` text,
`updated_at` datetime DEFAULT NULL,
`id` int(4) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

#21楼   回复  引用    

2008-09-24 11:43 by 8700new[未注册用户]
出现上面同样的问题:

# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
# Pick a unique cookie name to distinguish our session data from others'
session:session_key => '_depot_session_id'
model :cart
model :line_item
end

到model :cart
model :line_item 的地方就出现 Status: 500 Internal Server Error Content-Type: text/html 错误

sessions表也建了哦,具体什么原因呢?

#22楼   回复  引用    

2008-10-29 09:55 by iced_lily[未注册用户]
到application中把有个session前面的#去掉,就不会有500 Internal Server Error Content-Type: text/html 的报错了,昨天碰到的,晚上网上查到解决了
另问:我是按照英文版的代码一步一步抄下来的,显示购物车条目都没问题,但碰到想把数量合并时,总是提醒我,在做db:migration:ssesion :clear 之前一切都正常,跟书上显示的一样

name error in Store @add_to_cart
undefinded local variable or method 'cart_item' for

为什么啊,我是新手

#23楼   回复  引用    

2009-05-03 13:09 by 81959406
@jun1st
的确没有 呵呵

#24楼   回复  引用    

2009-05-03 13:42 by 81959406
No action responded to add_to_cart



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 811520




历史上的今天:
2004-07-09 使用WMI获取驱动器列表

相关文章:

相关链接: