IV 任务D:创建购物车
任务列表:
·会话和会话管理
·添加模型间的关系
·创建一个按钮,可添加产品到购物车中
一、迭代D1:寻找购物车
应用程序需要跟踪所有由买家添加到购物车中的商品。所以需要把购物车放到数据库中,并在会话中存储该购物车的唯一标识符cart.id。每当请求出现时,可以从会话中找到该购物车的标识,并用该标识在数据库中查找购物车。
1.创建一个购物车:
Administrator@JARRY /e/works/ruby/depot (master) $ rails generate scaffold cart SECURITY WARNING: No secret option provided to Rack::Session::Cookie. This poses a security threat. It is strongly recommended that you provide a secret to prevent exploits that may be possible from crafted cookies. This will not be supported in future versions of Rack, and future versions will even invalidate your existing user cookies. Called from: d:/dev/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/ session/abstract_store.rb:28:in `initialize'. invoke active_record create db/migrate/20130319021136_create_carts.rb create app/models/cart.rb invoke test_unit create test/unit/cart_test.rb create test/fixtures/carts.yml route resources :carts invoke scaffold_controller create app/controllers/carts_controller.rb invoke erb create app/views/carts create app/views/carts/index.html.erb create app/views/carts/edit.html.erb create app/views/carts/show.html.erb create app/views/carts/new.html.erb create app/views/carts/_form.html.erb invoke test_unit create test/functional/carts_controller_test.rb invoke helper create app/helpers/carts_helper.rb invoke test_unit create test/unit/helpers/carts_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/carts.js.coffee invoke scss create app/assets/stylesheets/carts.css.scss invoke scss identical app/assets/stylesheets/scaffolds.css.scss
2.
Administrator@JARRY /e/works/ruby/depot (master) $ rake db:migrate == CreateCarts: migrating ==================================================== -- create_table(:carts) -> 0.0781s == CreateCarts: migrated (0.0781s) ===========================================
3.
rails会话看上去像控制器的一个散列,所以将这个购物车id放在会话中,其可以使用符号:card_id建立索引。
/app/controllers/application_controller.rb
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
二、迭代D2:将产品放到购 物车中
购物车中包含了一些选购的货品。创建rails模型并应用迁移来创建相应的数据库表
1.
Administrator@JARRY /e/works/ruby/depot (master) $ rails generate scaffold line_item product_id:integer cart_id:integer SECURITY WARNING: No secret option provided to Rack::Session::Cookie. This poses a security threat. It is strongly recommended that you provide a secret to prevent exploits that may be possible from crafted cookies. This will not be supported in future versions of Rack, and future versions will even invalidate your existing user cookies. Called from: d:/dev/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middle ware/session/abstract_store.rb:28:in `initialize'. invoke active_record create db/migrate/20130319022813_create_line_items.rb create app/models/line_item.rb invoke test_unit create test/unit/line_item_test.rb create test/fixtures/line_items.yml route resources :line_items invoke scaffold_controller create app/controllers/line_items_controller.rb invoke erb create app/views/line_items create app/views/line_items/index.html.erb create app/views/line_items/edit.html.erb create app/views/line_items/show.html.erb create app/views/line_items/new.html.erb create app/views/line_items/_form.html.erb invoke test_unit create test/functional/line_items_controller_test.rb invoke helper create app/helpers/line_items_helper.rb invoke test_unit create test/unit/helpers/line_items_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/line_items.js.coffee invoke scss create app/assets/stylesheets/line_items.css.scss invoke scss identical app/assets/stylesheets/scaffolds.css.scss
2.
Administrator@JARRY /e/works/ruby/depot (master) $ rake db:migrate == CreateLineItems: migrating ================================================ -- create_table(:line_items) -> 0.0781s == CreateLineItems: migrated (0.0781s) =======================================
3.表建完了,现在在数据库中有地方来存放在线商品、购物车和产品之间的关系了。然而,rails应用程序并不是把这些关系放在数据库中。我们需要在模型文件中添加一些声明来说明它们之间的关系。
在/app/models下修改cart.rb添加has_many的调用:
class Cart < ActiveRecord::Base has_many :line_items, dependent: :destroy end
4.从相反的方向来定义连接,人在线商品到carts和products表。为了实现这个,要在文件line_item.rb中使用两次belongs_to声明:
/app/models/line_item.rb
class LineItem < ActiveRecord::Base belongs_to :product belongs_to :cart end
belongs_to声明放在哪里?简单地说,如果一个数据库表有外键,那么在相应的模型中每个外键都要有个belongs_to声明
5.出于完整性的考虑,应该在模型Product中也添加一个has_many指令。毕竟,如果我们有许多个购物车的话,每个产品也可以有多个在线商品引用它。这次我们用验证代码来避免删除那些正在被在线商品引用的产品。
/app/models/product.rb
class Product < ActiveRecord::Base default_scope order: 'title' has_many :line_items before_destroy :ensure_not_referenced_by_any_line_item # ... 之前的验证代码 private #ensure that there are no line items referencing this product def ensure_not_refrenced_by_any_line_item if line_items.empty? return true else errors.add(:base, 'Line Items present') return false end end end
三、迭代D3:添加一个按钮
模型间的关系处理完毕,该给每个产品添加一个Add to Cart按钮了。
我们不必创建新的控制器,甚至不必创建一个新的行为。脚手架生成器提供了:index、show、new、edit、create、update和destroy。我们正好可用的行为create。(行为new可能听上去也差不多,但是这个行为通常是要获得一个表单,可在其中输入某些信息,然后再由行为create继续下去。)
1.添加链接前我们使用了link_to,但链接默认使用http get方法。这里我们想用post,所以这次我们需要添加一个按钮,要用button_to方法。
可以通过指定url来将按钮和在线商品联系起来,但是rails可简单地将_path追加到控制器的名称后,用rails来处理,这里可以用line_items_path。
现在问题是哪个产品要添加到购物车中呢?这就需要把对应的产品id也传给这个方法。
/app/views/store/index.html.erb
<% 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, unit: "¥") %></span> <%= button_to 'Add to Cart', line_items_path(product_id: product) %> </div> </div> <% end %>
2.
/app/assets/stylesheets/store.css.scss
// Place all the styles related to the Store controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ /* START_HIGHLIGHT */ .store { h1 { margin: 0; padding-bottom: 0.5em; font: 150% sans-serif; color: #226; border-bottom: 3px dotted #77d; } /* An entry in the store catalog */ .entry { overflow: auto; margin-top: 1em; border-bottom: 1px dotted #77d; min-height: 100px; img { width: 80px; margin-right: 5px; margin-bottom: 5px; position: absolute; } h3 { font-size: 120%; font-family: sans-serif; margin-left: 100px; margin-top: 0; margin-bottom: 2px; color: #227; } //#START:inline p, div.price_line { margin-left: 100px; margin-top: 0.5em; margin-bottom: 0.8em; /* START_HIGHLIGHT */ form, div { display: inline; } /* END_HIGHLIGHT */ } //#END:inline .price { color: #44a; font-weight: bold; margin-right: 3em; } } } /* END_HIGHLIGHT */
3.添加按钮后效果
4.现在我们来修改LineItemsContorller以找到购物车中的内容。我们需要做的只是在/app/controllers/line_items_controller.rb的create方法中修改几行代码:
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.json { render json: @line_item, status: :created, location: @line_item } else format.html { render action: "new" } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end end
5.每当修改控制器功能时,我们知道需要更新相应的功能测试。在调用create方法时需要传递产品id给该方法,并将重定向的网址修改为我们想要的。通过修改/test/functional/line_items_controller_test.rb实现:
test "should create line_item" do assert_difference('LineItem.count') do post :create, product_id: products(:ruby).id end assert_redirected_to cart_path(assigns(:line_item).cart) end
6.rake test:functionals
7.显示购物车,创建简单的模板,/app/views/carts/show.html.erb:
<h2>Your Pragmatic Cart<h2> <ul> <% @cart.line_items.each do |item| %> <li><%= item.product.title %></li> <% end %> </ul>
8.点击add to cart添加到购物车后
相关推荐
Ruby on Rails Guides v2 - Ruby on Rails 4.2.5
在这个全球互联的世界中,计算机编程和 Web 应用程序开发都在迅猛发展,我很期待能为中国的开发者提供 Ruby on Rails 培训。学习英语这门世界语言是很重要的,但先通过母语学习往往会更有效果。正因为这样,当看到 ...
Ruby On Rails中文教材(PDF)
ruby on rails社区网站开发源码
Ubuntu系统ruby on rails安装 Ubuntu系统ruby on rails安装 Ubuntu系统ruby on rails安装 Ubuntu系统ruby on rails安装 Ubuntu系统ruby on rails安装 Ubuntu系统ruby on rails安装 Ubuntu系统ruby on rails安装 ...
简介 Ruby On Rails 框架自它提出之日...Rails 是一个真正彻底的 MVC(Model-View-Controller) 框架,Rails 清楚地将你的模型的代码与你的控制器的应用逻辑从 View 代码中分离出来。Rails 开发人员很少或者可能从未遇到
ruby on rails对mongodb的操作ruby on rails对mongodb的操作ruby on rails对mongodb的操作ruby on rails对mongodb的操作
Ruby on Rails入门经典-例子,有很多rails工程实例。
ruby on rails最新版 这是本人精心收集的重要软件
本书使用 Rails 默认的开发工具栈开发了一个完整的社交应用(类似 Twitter)。读完本书后你将掌握如何使用 Rails 从零开始开发任何类型的应用。这本书是《Ruby on Rails Tutorial, Third Edition》的简体中文版,由...
Windows7_Cygwin_Git_RVM_Ruby1.9.3_Rails3_MongoD B_Nginx_Unicorn_Rspec_Guard_Spork(2-Ruby on Rails3 安装配置
Ruby on Rails Web开发学习实录 内容简介: 在目前的主流web开发技术中,基于ruby语言的rails框架是做网站开发速度最快的工具。它可以达到j2ee框架开发速度的5~10倍,并且代码量也非常少。另外由于代码量的大幅度...
Ruby on Rails的性能调优方案研究,张淼森,杨杰,Ruby on Rails 框架自它提出之日起就受到广泛关注。由于Rails框架基于MVC(Model-View-Controller) 模型,可以清楚地将模型层的代码与控制层的应
Ruby on Rails中文指南
ruby on rails api方便查阅
ruby on rails 教程源码,配合原书使用
ruby on rails 开发环境包(ruby1.8.7,rails2.2.3)