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

时间:2015-02-04 10:12:15

标签: ruby-on-rails database-migration

我正在尝试构建一个虚拟仓库。数据库中的一列将包含仓库中应该具有固定值的位置列表。仓库分为过道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的类,我在这个类中有一个名为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

我的目标是创建一个页面,用户可以从可用列表中选取一个位置,并将产品,其大小写的重量和数量设置到此位置。后来我想编制分发操作,但现在让我们解决这个问题。

3 个答案:

答案 0 :(得分:1)

我首先重构代码。这些方面的东西:

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。此外,不应在此处使用全局变量或实例变量,因为它们仅供本地使用。只是简单的局部变量是可以的。所以代码有点改变,以便返回位置列表而不是修改全局var,你只需按如下方式使用它:

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

答案 1 :(得分:0)

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

t.string:location,默认:“您的值”

纠正我如果我理解你的要求是错误的。

答案 2 :(得分:0)

在我看来,您不是在寻找“默认值”,而是在视图表单中显示该值的可用性列表的方法。

# 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 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