Agile Web Development with Rails第九章笔记——任务D:创建购物车
2013-05-23 10:18
399 查看
本章内容:
会话和会话管理
添加模型间的关系
创建一个按钮,可添加产品到购物车中
迭代D1:寻找购物车
将购物车放在数据库中,并在会话中存储该购物车的唯一标识符,cart.id。每当请求出现时,可以从会话中找到该购物车的标识,并用该标识在数据库中查找购物车。
1、创建购物车
rails generate scaffold cart
![](http://img.blog.csdn.net/20130523095518955)
2、应用迁移
rake db:migrate
![](http://img.blog.csdn.net/20130523095603950)
3、修改控制器app/controllers/application_controller.rb
Rails的会话像是一个散列,将购物车对应的数据库id(cart.id)赋值给标识符为cart_id的session中。
迭代D2:将产品放到购物车中
1、创建在线商品表存放在线商品、购物车和产品之间的关系。
如图所示,在线商品line_items描述了购物车carts和商品products之间的关系。
![](http://img.blog.csdn.net/20130524204907423)
创建Rails模型:
rails generate scaffold line_item product_id:integer cart_id:integer
应用迁移来创建相应的数据库表:
rake db:migrate
2、修改模型文件
在模型文件中添加一些声明来说明在线商品、购物车和产品之间的关系。(牵扯到cart、product和line_item的模型文件)
打开app/models下的文件cart.rb,添加一个对has_many的调用:
![](http://img.blog.csdn.net/20130524200530989)
has_many :line_items一个购物车有许多相关联的在线商品。
:dependent => :destroy在线商品的存在依赖于购物车是否存在。
从相反的方向定义关系(从在线商品到carts和products表),修改app/models/line_item.rb
![](http://img.blog.csdn.net/20130524201453842)
注:如果一个数据库表有外键,那么在相应模型中每个外键都要有个belongs_to声明。
belongs_to告诉Rails数据库,表line_items中的数据是依赖于表carts和表products的。
因为每个产品都可以有多个在线商品引用它,故需要在模型product中添加一个has_many指令。
上面的代码声明了一个产品有多个在线商品,并定义了一个hook(钩子)方法叫
ensure_not_referenced_by_any_line_itme。
hook方法就是在对象的生命周期中某个给定的地方Rails会自动调用的方法。
迭代D3:添加一个按钮
现在模型间的关系处理完毕,该给每个产品添加一个Add to Cart按钮了。
1、修改视图页面,使用line_items_path指定处理动作的控制器为在线产品控制器,向控制器传入欲加入购物车产品的id
![](http://img.blog.csdn.net/20130602144502046)
2、修改在线商品控制器的create方法。
将产品id传递给create方法,以便唯一的标识要添加的产品。
修改后的create方法如下:
![](http://img.blog.csdn.net/20130602153253859)
跳转界面模板:
3、结果测试
完成上述步骤之后点击Add to Cart按钮,但是报错如下
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/wail.gif)
![](http://img.blog.csdn.net/20130602180941500)
百度发现大家都遇到了这个bug,应该是版本差别所致。
由于写了“@cart.line_items.build(:product
=> product)”这句,这里要求必须把product属性放入attr_accessible中
原因在此
http://guides.rubyonrails.org/security.html#mass-assignment
为了安全考虑,如果允许mass-assignment的话,可以通过链接往数据库里插入数据
所以默认不可以直接用build来new这个新对象,除非加上
attr_accessible :product,:cart 允许mass-assignment。
修改模型层文件
![](http://img.blog.csdn.net/20130602182857859)
重新测试,运行正常:
会话和会话管理
添加模型间的关系
创建一个按钮,可添加产品到购物车中
迭代D1:寻找购物车
将购物车放在数据库中,并在会话中存储该购物车的唯一标识符,cart.id。每当请求出现时,可以从会话中找到该购物车的标识,并用该标识在数据库中查找购物车。
1、创建购物车
rails generate scaffold cart
2、应用迁移
rake db:migrate
3、修改控制器app/controllers/application_controller.rb
Rails的会话像是一个散列,将购物车对应的数据库id(cart.id)赋值给标识符为cart_id的session中。
class ApplicationController < ActionController::Base protect_from_forgery private def current_cart Cart.find(session[:cart_id]) rescue ActiveRecord::RecordNotFound cart=Cart.create session[:cart_id]=cart.id cart end end先从session对象中得到:cart_id,试图寻找与该id对应的购物车。如果没有找到,创建新的cart,并将新购物车的id保存在会话中。
迭代D2:将产品放到购物车中
1、创建在线商品表存放在线商品、购物车和产品之间的关系。
如图所示,在线商品line_items描述了购物车carts和商品products之间的关系。
创建Rails模型:
rails generate scaffold line_item product_id:integer cart_id:integer
应用迁移来创建相应的数据库表:
rake db:migrate
2、修改模型文件
在模型文件中添加一些声明来说明在线商品、购物车和产品之间的关系。(牵扯到cart、product和line_item的模型文件)
打开app/models下的文件cart.rb,添加一个对has_many的调用:
has_many :line_items一个购物车有许多相关联的在线商品。
:dependent => :destroy在线商品的存在依赖于购物车是否存在。
从相反的方向定义关系(从在线商品到carts和products表),修改app/models/line_item.rb
注:如果一个数据库表有外键,那么在相应模型中每个外键都要有个belongs_to声明。
belongs_to告诉Rails数据库,表line_items中的数据是依赖于表carts和表products的。
因为每个产品都可以有多个在线商品引用它,故需要在模型product中添加一个has_many指令。
class Product < ActiveRecord::Base attr_accessible :description, :image_url, :price, :title validates :title, :description, :image_url, :presence => true validates :price, :numericality => {:greater_than_or_equal_to => 0.01} validates:title, :uniqueness => true validates :image_url, :format => { :with => %r{\.(gif|jpg|png)$}i, :message => 'must be a URL for GIF,JPG or PNG image.' } default_scope :order => 'title' has_many :line_items before_destroy :ensure_not_referenced_by_any_line_itme private def ensure_not_referenced_by_any_line_itme if line_items.empty? return true else errors.add(:base,'Line Items present') return false end end end
上面的代码声明了一个产品有多个在线商品,并定义了一个hook(钩子)方法叫
ensure_not_referenced_by_any_line_itme。
hook方法就是在对象的生命周期中某个给定的地方Rails会自动调用的方法。
迭代D3:添加一个按钮
现在模型间的关系处理完毕,该给每个产品添加一个Add to Cart按钮了。
1、修改视图页面,使用line_items_path指定处理动作的控制器为在线产品控制器,向控制器传入欲加入购物车产品的id
<% if notice %> <p id="notice"><%= notice %></p> <% end %> <h1>Your Pragmatic Catalog</h1> <% @products.each do |product| %> <div class="entry"> <%= image_tag(product.image_url) %> <h3><%= product.title %></h3> <%= sanitize(product.description) %> <div class="price_line"> <span class="price"><%= number_to_currency(product.price) %></span> <%= button_to 'Add to Cart', line_items_path(:product_id => product) %> </div> </div> <% end %>修改效果:
2、修改在线商品控制器的create方法。
将产品id传递给create方法,以便唯一的标识要添加的产品。
修改后的create方法如下:
# POST /line_items # POST /line_items.xml def create @cart = current_cart product = Product.find(params[:product_id]) @line_item = @cart.line_items.build(:product => product) respond_to do |format| if @line_item.save format.html { redirect_to(@line_item.cart, :notice => 'Line item was successfully created.') } format.xml { render :xml => @line_item, :status => :created, :location => @line_item } else format.html { render :action => "new" } format.xml { render :xml => @line_item.errors, :status => :unprocessable_entity } end end end如以上代码所示,这部分的操作可以总结为:
跳转界面模板:
<h2>Your Pragmatic Cart</h2> <ul> <% @cart.line_items.each do |item| %> <li><%= item.product.title %></li> <% end %> </ul>
3、结果测试
完成上述步骤之后点击Add to Cart按钮,但是报错如下
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/wail.gif)
百度发现大家都遇到了这个bug,应该是版本差别所致。
由于写了“@cart.line_items.build(:product
=> product)”这句,这里要求必须把product属性放入attr_accessible中
原因在此
http://guides.rubyonrails.org/security.html#mass-assignment
为了安全考虑,如果允许mass-assignment的话,可以通过链接往数据库里插入数据
所以默认不可以直接用build来new这个新对象,除非加上
attr_accessible :product,:cart 允许mass-assignment。
修改模型层文件
重新测试,运行正常:
相关文章推荐
- Agile Web Development with Rails第十章笔记——任务E:更智能的购物车
- Agile Web Development with Rails第六章笔记——任务A:创建应用程序
- Agile Web Development with Rails第十一章笔记——任务F:Ajax初体验
- Agile Web Development with Rails第十二章笔记——任务G:付款
- Agile Web Development with Rails第七章笔记——任务B:验证
- Agile Web Development with Rails第八章笔记——任务C:商品目录显示
- Agile Web Development with Rails 读书笔记 (三)
- agile WEB development with rails的笔记
- Agile Web Development with Rails 读书笔记 (一)
- Agile Web Development with Rails 读书笔记 (四)
- Agile Web Development with Rails 读书笔记 (二)
- Agile Web Development with Rails 翻译(一)
- Agile Web Development with Rails 翻译(十四)
- Rails新书出版了:Agile Web Development with Ruby on Rails
- 《Agile Web Development with Rails》读书笔记(四)
- Agile Web Development with Rails 翻译(二)
- Agile Web Development with Rails 翻译(十五)
- 开始读《Agile Web Development with Rails》
- Agile Web Development With Rails下载
- Agile Web Development with Rails 翻译(十六)