本章内容:
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保存在会话中。
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:添加一个按钮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按钮,但是报错如下
百度发现大家都遇到了这个bug,应该是版本差别所致。
由于写了“@cart.line_items.build(:product => product)”这句,这里要求必须把product属性放入attr_accessible中