2

我正在创建一个可以添加/删除模型字段的 Rails 代码。

我有一个模型库存,我可以在其中添加如下字段列表:

def update_new_fields
  @fieldnames = params["fieldnames"]

  @fieldnames.each do |fieldname|
    ActiveRecord::Migration.add_column(Inventory, fieldname, :string)
  end    
end

查看更新字段列表

def index
  reload!
  @fields=Inventory.attribute_names
  respond_to do |format|
    format.html 
  end
end

但是,我有以下错误:

undefined method `reload!' for #<InventoriesController:0x007fccf70b7720>

如果我重新加载!在控制台中:

2.0.0 :163 >   ActiveRecord::Migration.remove_column(Inventory, "f", :string)
-- remove_column(Inventory(id: integer, name: string, description: string, quatity: integer, created_at: datetime, updated_at: datetime, a: string, b: string, c: string, e: string, f: string), "f", :string)
   (122.9ms)  ALTER TABLE `inventories` DROP `f`
   -> 0.1232s
 => nil
2.0.0 :164 > Inventory.reset_column_information
 => nil
2.0.0 :165 > Inventory.attribute_names
 => ["id", "name", "description", "quatity", "created_at", "updated_at", "a", "b", "c", "e", "f"]
2.0.0 :166 > reload!
Reloading...
 => true
2.0.0 :167 > Inventory.attribute_names
 => ["id", "name", "description", "quatity", "created_at", "updated_at", "a", "b", "c", "e"]

有用。

UPD

我发现,在找到“Inventory.reset_column_information”之后,attribute_names 没有更新,但 Class 信息是:

2.0.0 :090 > Inventory.reset_column_information
 => nil
2.0.0 :091 > Inventory.attribute_names
 => ["id", "name", "description", "quatity", "created_at", "updated_at", "hello", "next"]
2.0.0 :092 > Inventory
 => Inventory(id: integer, name: string, description: string, quatity: integer, created_at: datetime, updated_at: datetime, a: string, b: string, c: string, d: string)

所以,我所做的工作是:

def index
  Inventory.reset_column_information
  tmp = Inventory.new
  @fields=tmp.attribute_names
  respond_to do |format|
    format.html 
  end
end

最后我在 Inventory 中的字段被更新了。

4

1 回答 1

2

虽然我想知道你为什么需要这个,但看起来很奇怪。但实际上您正在寻找的是刷新模型列信息。可以这样做:

Inventory.reset_column_information

UPD

可能是因为类被缓存了。您可以使用重新加载单个类load

load "#{Rails.root}/app/models/inventory.rb"

虽然它会发出一些关于重新定义的警告。您可以在实际再次加载之前使用remove_const方法以避免警告。

remove_const "Inventory"
load "#{Rails.root}/app/models/inventory.rb"

但请注意,这样做可能会导致生产环境出错。如果您使用多个 rails 实例,则该代码只会在一个上重新加载该类!所以三思而后行,也许还有其他方法可以实现您实际在做的事情。我强烈不建议走这条路。

于 2013-10-13T09:42:12.243 回答