`
jarry-li
  • 浏览: 43526 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Ruby On Rails的第一个应用(六)--创建购物车

阅读更多

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添加到购物车后

分享到:
评论

相关推荐

    SOA系列:开源框架Ruby on Rails

    - **2004年**:David Heinemeier Hansson 发布了 Ruby on Rails 的第一个版本。这一事件标志着 Rails 的正式诞生,同时也推动了 Ruby 语言的发展。 - **快速发展期**:自从 Rails 发布之后,Ruby 社区经历了快速...

    rails敏捷开发的购物车系统

    在本文中,我们将深入探讨如何使用Rails敏捷开发技术构建一个购物车系统,特别是在参考《rails敏捷开发第四版》中的示例。Rails 3.2.6是本文的基础框架,它是一个强大的Ruby Web应用程序框架,以其MVC(模型-视图-...

    Secrets of ruby on rails

    例如,在创建一个新的Rails应用时,默认情况下会自动配置数据库连接、路由规则等,开发者无需手动编写大量的配置代码。这种方式不仅简化了开发流程,还提高了开发效率,使得开发者能够将更多精力放在业务逻辑的实现...

    无线点餐系统的服务端,使用ruby on rails框架

    Ruby on Rails(简称Rails)是一款基于Ruby语言的开源Web应用程序框架,遵循MVC(Model-View-Controller)架构模式,为开发人员提供了快速开发、简洁代码以及强大的数据库支持。 首先,让我们深入了解Ruby on Rails...

    web开发之rails最新调试通过购物车代码

    在Web开发领域,Ruby on Rails(简称Rails)是一种流行的开源框架,它基于MVC(Model-View-Controller)架构模式,用于快速构建高效、可维护的Web应用。本压缩包中的"web开发之rails最新调试通过购物车代码"是关于...

    Ruby-Rails实战之B2C商城开发

    在本项目"Ruby-Rails实战之B2C商城开发"中,我们将深入探索使用Ruby on Rails这一强大的Web开发框架来构建一个完整的B2C(Business-to-Consumer)在线商城。Rails是Ruby语言的一个核心框架,以其MVC(Model-View-...

    Bootstrap-ShoppingCart:使用Ruby on Rails中的引导程序开发的购物车应用程序

    Bootstrap-ShoppingCart是一个基于Ruby on Rails框架开发的购物车应用程序,它充分利用了Twitter Bootstrap的前端设计工具,为用户提供了一个简洁、响应式的界面。这个项目旨在帮助开发者了解如何将Rails的强大功能...

    e-commerce-on-rails:一个非常简单的 Ruby on Rails 电子商务,带有活动管理员

    Ruby on Rails(RoR)是一个基于Ruby语言的开源Web应用程序框架,它遵循模型-视图-控制器(MVC)架构模式,旨在提高开发效率和可读性。"e-commerce-on-rails"项目就是一个使用Rails搭建的简单电子商务平台,特别加入...

    《web开发敏捷之道 应用rails进行敏捷web开发》(第一版)的depot源代码

    1. **Ruby on Rails**:Rails是基于Ruby语言的一个开源Web开发框架,它遵循“约定优于配置”(Convention over Configuration, CoC)和“Don't Repeat Yourself”(DRY)的原则,简化了Web应用的开发流程。...

    shop:使用Ruby On Rails购买回购

    在本项目中,我们主要探讨的是如何利用Ruby on Rails框架构建一个购物平台,重点在于实现产品的回购功能。Ruby on Rails(简称Rails)是一款基于Ruby语言的开源Web开发框架,它遵循MVC(Model-View-Controller)架构...

    rails 项目起步示例

    Rails是Ruby语言的一个著名Web开发框架,全称为Ruby on Rails,它遵循MVC(Model-View-Controller)架构模式,旨在提高开发效率和代码可读性。本示例"rails项目起步示例"是一个购物系统,非常适合初学者入门学习。 ...

    Web 开发敏捷之道(应用Rails 进行敏捷Web 开发第三版)

    **Rails**,全称为 **Ruby on Rails**,是一种用于构建 Web 应用的开源框架,由 David Heinemeier Hansson 在 2004 年首次发布。Rails 自诞生以来,便以其独特的设计理念迅速吸引了全球开发者的关注。随着 Web 2.0 ...

    Agile Web Development with Rails-Second Edition-Beta一书例子

    这个项目可能是从创建一个新的Rails应用开始,逐步添加功能,如用户认证、购物车、支付处理等,这些都是Web开发中的常见需求。 Rails是一个流行的开源Web应用程序框架,遵循MVC(模型-视图-控制器)架构模式。在...

    Rails 3 in Action

    第十八章讨论了 **基于 Rack 的应用程序**,Rack 是一个为 Ruby Web 应用程序提供通用接口的轻量级框架。 - **Rack**: - 使 Rails 应用与其他 Web 框架兼容。 - 支持中间件,增加功能或修改请求/响应。 综上所...

    rails敏捷开发,我的成功之路

    ### 知识点四:第一个Rails应用 **标题与描述**:本书通过一个简单的“Hello, Rails”示例来引导读者快速上手,掌握创建新应用的基本流程。 **详细说明**: - **创建新应用**:使用`rails new`命令初始化一个新的...

Global site tag (gtag.js) - Google Analytics