购物车有多种型号

时间:2014-09-03 07:43:32

标签: ruby-on-rails

我们建立了(基于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方法,以便我们可以在购物车中添加房屋和公寓?

THanks remco

1 个答案:

答案 0 :(得分:0)

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

enter image description here

只有当您能够在同一模型中关联不同对象时,才能

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模型中