【问题标题】:Shopping cart with multiply models具有多种模型的购物车
【发布时间】:2014-09-03 07:43:31
【问题描述】:

我们(基于 Agile webdev Rails4 一书)构建了一个购物/查询车。

访客可以将line_items(房屋)添加到购物车,然后结帐。当访客结帐时,会创建潜在客户。

我的模特:

class House < ActiveRecord::Base
has_many :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :lead


  belongs_to :house

  belongs_to :cart

end



 class Lead < ActiveRecord::Base
    has_many :line_items, dependent: :destroy



  def add_line_items_from_cart(cart)
    cart.line_items.each do |item|
      line_items << item
    end
  end

end

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy
  accepts_nested_attributes_for :line_items


end

用于创建会话购物车的模块

module CurrentCart
  extend ActiveSupport::Concern

  private

    def set_cart 
      @cart = Cart.find(session[:cart_id])
    rescue ActiveRecord::RecordNotFound
      @cart = Cart.create
      session[:cart_id] = @cart.id 
    end
end

Carts_controller

class CartsController < ApplicationController
  before_action :set_cart, only: [:show, :edit, :update, :destroy]

    def create
        @cart = Cart.new(cart_params)

        respond_to do |format|
          if @cart.save
            format.html { redirect_to @cart, notice: 'Cart was successfully created.' }
            format.json { render action: 'show', status: :created, location: @cart }
          else
            format.html { render action: 'new' }
            format.json { render json: @cart.errors, status: :unprocessable_entity }
          end
        end
      end
    end

Line_item 控制器

class LineItemsController < ApplicationController
  skip_before_action :authorize, only: :create
  include CurrentCart
  before_action :set_cart, only: [:create]
  before_action :set_line_item, only: [:show, :edit, :update, :destroy]

def create

    house = House.find(params[:house_id])
    @line_item = @cart.line_items.build(house_id: house.id)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to @line_item.cart,
          notice: 'Vakantiehuis toegevoegd in lijst.' }
        format.json { render action: 'show',
          status: :created, location: @line_item }
      else
        format.html { render action: 'new' }
        format.json { render json: @line_item.errors,
          status: :unprocessable_entity }
      end
    end
  end

leads_controller

class LeadsController < ApplicationController
  include CurrentCart
  before_action :set_cart, only: [:new, :create]

 def create
    @lead = Lead.new(lead_params)
    @lead.add_line_items_from_cart(@cart)

    respond_to do |format|
      if @lead.save

        format.html { redirect_to @lead, notice: 
          'Thank you for your order.' }
        format.json { render action: 'show', status: :created,
          location: @order }

      else
        format.html { render action: 'new' }
        format.json { render json: @lead.errors,
          status: :unprocessable_entity }
      end

    end

  end
end

我们想添加一个新模型(将公寓添加到购物车)。所以我在 line_items 表中添加了 apartment_id 并更改了模型

class Apartment < ActiveRecord::Base
    has_many :line_items
    end


class LineItem < ActiveRecord::Base
      belongs_to :lead


      belongs_to :house
      belongs_to :apartment


      belongs_to :cart

    end

但我现在不知道如何更改 LineItems_controller 中的 create 方法,以便我们可以将房屋和公寓添加到购物车?

谢谢雷姆科

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    您需要将line_items 模型更改为polymorphic association

    Polymorphic associations 只是当您能够关联同一模型中的不同对象时。如果您的 apartmentsHouse 模型的子对象,这将是不正确的,但由于它们是独立的,您将能够多态地关联它们

    我会这样做:

    #app/models/line_item.rb
    class LineItem < ActiveRecord::Base
       belongs_to :item, polymorphic: true
    end
    
    #app/models/house.rb
    class House < ActiveRecord::Base
       has_many :line_items, as: :items
    end
    
    #app/models/apartment.rb
    class Apartment < ActiveRecord::Base
       has_many :line_items, as: :items
    end
    

    这将使您能够执行以下操作:

    #app/controllers/line_items.controller.rb
    class LineItemsController < ApplicationController
       before_action :create_object
    
       def create
          @line_item = @cart.line_items.build item: @object
          @line_items.save
       end
    
       private
    
       def create_object
          id = params[:house_id] || params[:apartment_id]
    
          model = "House" if params[:house_id]
          model = "Apartment" if params[:apartment_id]
          model. constantize
    
          @object = model.find id
       end
    end
    

    这应该引用正确的模型,以便您将公寓或房屋保存到您的 LineItem 模型

    【讨论】:

    • 谢谢...丰富...我要改变...让你知道结果是什么!
    • 我试过了,但我得到错误“未定义的方法 `find' for "House":String" 这是代码:def create_object id = params[:house_id] || params[:appartment_id] model = "House" if params[:house_id] model = "Apartment" if params[:apartment_id] model.constantize @object = model.find.id end
    • 我认为最后一行不正确.. @object = model.find.id
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 2017-11-24
    • 1970-01-01
    • 2012-03-31
    相关资源
    最近更新 更多