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