如何在其中一列中预定义固定值

How to predefine fixed values in one of the columns

我正在尝试建立一个虚拟仓库。数据库中的一列将包含仓库内的位置列表,该列表应该具有固定值。仓库被分成 DA 到 GA 的通道,每个通道被分成位置 011 到 603。有一个横向通道穿过所有通道,消除了某些位置(我实际上来自一个真实的现有仓库)。其他栏是产品名称、产品重量和数量。我的迁移代码如下所示:

  def change
create_table :locations do |t|
  t.string :location # this column is supposed to have fixed values
  t.string :product   # name of a product like CocaCola Zero 8x2L
  t.decimal :product_weight
  t.integer :quantity

  t.timestamps
end

在一个单独的文档中,我制作了一个名为 Locations 的 class 并且我在这个 class 中有一个名为 def numbers_letters 的方法,它生成位置列表:

def numbers_letters
  @digit = 3
  aisle_number = 0
  odd_list = []
  even_list = []
  for @letter in "DA".."GA"
    aisle_number = aisle_number + 1
    @letter.next!
    while @digit < 604
      @digit += 8
      if aisle_number.odd?
        odd_list << @digit
      else
        even_list << @digit
      end
      @digit += 2
      if aisle_number.odd?
        odd_list << @digit
      else
        even_list << @digit
      end
    end
    @digit = 3
    odd_list.each do |odd|
      if odd > 350 && odd < 604
        od = format('%003d', odd)
        $list_of_locations << @letter + od
      elsif odd < 322 && odd > 3
        od = format('%003d', odd)
        $list_of_locations << @letter + od
      end
    end
    even_list.each do |even|
      if even > 300 and even < 604
        ev = format('%003d', even)
        $list_of_locations << @letter + ev
      elsif even > 3 and even < 262
        ev = format('%003d', even)
        $list_of_locations << @letter + ev
      end
    end
    odd_list = []
    even_list = []
  end
end

我的目标是制作一个页面,用户可以在该页面上从可用列表中选择一个位置,并将产品、包装箱的重量和数量设置到该位置。稍后我想对分发操作进行编程,但现在让我们先解决这个问题。

我不明白你的要求,但在你的迁移文件中设置了以下内容

t.string:位置,默认:"Your value"

如果我理解你的要求有误,请纠正我。

我会先大量重构代码。这些方面的内容:

def numbers_letters
  list_of_locations = []
  aisle_number = 0
  odd_list = []
  even_list = []

  ('DB'..'GB').each do |letter|
    aisle_number += 1

    rng = (11..604)
    rng.step(8).each do |digit|
      if aisle_number.odd?
        odd_list << digit << digit + 2
      else
        even_list << digit << digit + 2
      end
    end

    odd_list.each do |odd|
      list_of_locations << letter + format('%003d', odd) if odd > 350 || odd < 322
    end
    even_list.each do |even|
      list_of_locations << letter + format('%003d', even) if even > 300 || even < 262
    end
  end

  list_of_locations
end

即用each代替for,利用rangestep。此外,不应在此处使用全局变量或实例变量,因为它们仅供本地使用。只是普通的局部变量就可以了。所以代码稍微改变了一点,这样它 returns 位置列表而不是修改全局变量,你只需按如下方式使用它:

list_of_locations = numbers_letters

将它们添加到数据库:

class AddPredefinedLocations < ActiveRecord::Migration
  # assumes class PredefinedLocation < ActiveRecord::Base in app/models
  def up
    create_table :predefined_locations do
      t.string :location
    end

    numbers_letters.each do |loc|
      PredefinedLocation.create location: loc
    end
  end

  def down
    drop_table :predefined_locations
  end
end

在我看来,您并不是在寻找 "default value",而是在寻找一种在视图表单中显示该值的可能性列表的方法。

# app/models/location.rb
class Location < ActiveRecord::Base

  def numbers_letters
    #  EdwardM code here
  end
end

# app/controllers/locations_controller.rb
class LocationsController < ApplicationController

  def new
    @location = Location.new
  end

  def create
    @location = Location.new params[:location]
    @location.save
    respond_with @location
  end
end

# app/views/locations/new.html.erb
<%= form_for @location do |f| %>
  First name: <%= f.text_field :product %><br />
  Last name : <%= f.text_field :quantity %><br />
  location  : <%= f.select(:location, @location.numbers_letters) %>

  <%= f.submit %>
<% end %>

```

这是您要找的吗?

如果是这样请注意,也许您应该考虑拥有 2 个位置,而不是生成所有可能的字母数字组合的庞大列表

类似于:

def change
  create_table :locations do |t|
    t.string :aisle  # CG
    t.string :location  # number
    t.string :product   # name of a product like CocaCola Zero 8x2L
    t.decimal :product_weight
    t.integer :quantity
    t.timestamps
end

因此您将设置:

location = Location.new(aisle: 'CG', location '123')
location.save

注:

@location.numbers_letters 只是演示,您也许应该考虑使用 class 方法,例如

class Location < ActiveRecord::Base
  def self.available_aisiles 
    "DA".."GA"
  end

  def self.available_locations
    '011'..'603'
  end
end

# and then call

Location.available_locations
Location.available_aisiles