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" имена атрибутов не были обновлены, но информация о классе:

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 обновляется.

1 ответ

Хотя мне интересно, зачем Вам это нужно, выглядит очень странно. Но на самом деле вы ищете, чтобы обновить информацию о столбце модели. Это можно сделать так:

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, этот код перезагрузит класс только на одном! Поэтому подумайте дважды, может быть, есть альтернативы, как добиться того, что вы на самом деле делаете. Я настоятельно не рекомендую идти по этому пути.

Другие вопросы по тегам