Ruby on rails 基于数据库中库存可用性的动态下拉列表-Rails 4

Ruby on rails 基于数据库中库存可用性的动态下拉列表-Rails 4,ruby-on-rails,ruby,ruby-on-rails-4,Ruby On Rails,Ruby,Ruby On Rails 4,我正在创建一个电子商务网站,我有一个“大小”下拉列表供客户选择大小。我想要的是,下拉菜单只显示根据数据库中的“库存”值可用的大小 有没有人有这样做的经验或有什么见解 在架构中调整表的大小 create_table "sizes", force: true do |t| t.integer "product_id" t.integer "stock" t.string "size" t.datetime "created_at" t.datetime

我正在创建一个电子商务网站,我有一个“大小”下拉列表供客户选择大小。我想要的是,下拉菜单只显示根据数据库中的“库存”值可用的大小

有没有人有这样做的经验或有什么见解

在架构中调整表的大小

create_table "sizes", force: true do |t|
    t.integer  "product_id"
    t.integer  "stock"
    t.string   "size"
    t.datetime "created_at"
    t.datetime "updated_at"
end
Size.rb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>
类大小
订购产品.rb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>
class OrderProduct
Product.rb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>
类产品
product/show.html.erb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>


非常感谢

我希望我完全理解你想要做什么;您应该能够使用
pull
选择所有可用的大小值,如下所示:

@product.sizes.where('stock >= 1').pluck(:size, :id)

编辑:参见Douglas F Shearer的文章,scope是一个比在视图中放置Ruby代码更优雅的解决方案

我希望我完全理解你想要做什么;您应该能够使用
pull
选择所有可用的大小值,如下所示:

@product.sizes.where('stock >= 1').pluck(:size, :id)

编辑:参见Douglas F Shearer的文章,scope是一个比在视图中放置Ruby代码更优雅的解决方案

在尺寸模型中添加一个范围,并使用该范围填充选择字段

范围:

class Size < ActiveRecord::Base

  belongs_to :product

  scope :in_stock, where('stock > 0')

end
类大小0')
结束
选择字段:

<%= f.input :size, as: :select, collection: @product.sizes.in_stock, selected: 0, required: false %>


在视图中使用范围而不是筛选,可以在其他位置重复使用库存范围,并执行SQL查询,而不是加载所有记录并遍历所有记录。

将范围添加到大小模型中,并使用此来填充选择字段

范围:

class Size < ActiveRecord::Base

  belongs_to :product

  scope :in_stock, where('stock > 0')

end
类大小0')
结束
选择字段:

<%= f.input :size, as: :select, collection: @product.sizes.in_stock, selected: 0, required: false %>


在视图中使用范围而不是过滤,可以让您在其他地方重复使用库存范围,并执行SQL查询,而不是加载所有记录并遍历所有记录。

从@Douglas的答案中得到启发,我发现以下方法可行

Product.rb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>
类产品0')
结束
结束
product/show.html.erb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>


谢谢你的帮助

从@Douglas的答案中获得灵感,我发现以下方法可行

Product.rb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>
类产品0')
结束
结束
product/show.html.erb

class Size < ActiveRecord::Base

    belongs_to :product
end
class OrderProduct < ActiveRecord::Base

  belongs_to :order
  belongs_to :product
  belongs_to :size
end
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes
end
<%= simple_form_for :basket, url: product_basket_path(@product), remote: true do |f| %>

<%= f.input :quantity, as: :select, collection: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], selected: 1, required: false %>

<%= f.input :size, as: :select, collection: @product.sizes, selected: 0, required: false %>

<%= f.button :submit, "Add to basket" %>

<% end %>
class Product < ActiveRecord::Base

    has_many :order_products
    has_many :orders, through: :order_products
    has_many :sizes

    def in_stock
        self.sizes.where('stock > 0')
    end
end
<%= f.input :size, as: :select, collection: @product.in_stock, selected: 0, required: false %>



谢谢你的帮助

谢谢@Douglas,这听起来像是两个中比较好的一个。但是,当我将“大”的库存减少到0并查看下拉列表时,它会显示所有大小,包括“大”,但也会显示“小”和“中”,即“小”“中”“大”“小”“中”。有什么想法吗?谢谢,我认为这里的问题是,在我的尺码表中,我有其他尺码为“小”、“中”和“大”的产品,因此它也会在下拉列表中显示这些产品。不确定这里的解决方案是什么?如果您使用@product.size.in_库存,则应该只使用与该产品相关的尺寸。如果出现多个,则每个产品必须有多个相同的尺寸。在尺寸上添加一个唯一性验证如何,范围是产品ID?谢谢您的帮助,@Douglas。我试过了,但似乎都不起作用。问题似乎是,通过在尺寸模型中设置范围,所有尺寸都会显示出来,而不管产品是什么。为了解决这个问题,我在产品模型中创建了一个方法,该方法复制了DouglasThanks@Douglas建议的范围功能,这听起来是两个方法中比较好的一个。但是,当我将“大”的库存减少到0并查看下拉列表时,它会显示所有大小,包括“大”,但也会显示“小”和“中”,即“小”“中”“大”“小”“中”。有什么想法吗?谢谢,我认为这里的问题是,在我的尺码表中,我有其他尺码为“小”、“中”和“大”的产品,因此它也会在下拉列表中显示这些产品。不确定这里的解决方案是什么?如果您使用@product.size.in_库存,则应该只使用与该产品相关的尺寸。如果出现多个,则每个产品必须有多个相同的尺寸。在尺寸上添加一个唯一性验证如何,范围是产品ID?谢谢您的帮助,@Douglas。我试过了,但似乎都不起作用。问题似乎是,通过在尺寸模型中设置范围,所有尺寸都会显示出来,而不管产品是什么。为了解决这个问题,我在产品模型中创建了一个方法,该方法复制了DouglasThanks@Rudolf建议的范围功能。在我去查看我的篮框之前,这一切都如期进行。问题是,
:size
作为字符串而不是控制器期望的大小id发送。将
:size
更改为
:id
可以解决此问题,但下拉列表显示的是id,而不是人类可读的字符串。试图找出解决办法??啊,现在我明白了!我调整了答案,见上文。谢谢@Rudolf,我想我已经试过了,但显然没有!那么,这就是解决方案?如果你接受它作为正确的答案,我将包括道格拉斯的建议,并写它作为一个范围!谢谢你,鲁道夫。在我去查看我的篮框之前,这一切都如期进行。问题在于
:大小