Reputation: 762
I'm creating a rails code that could add/remove field of a model.
I've a model Inventory, where I could add a list of fields as below:
def update_new_fields
@fieldnames = params["fieldnames"]
@fieldnames.each do |fieldname|
ActiveRecord::Migration.add_column(Inventory, fieldname, :string)
end
end
To view list of updated fields
def index
reload!
@fields=Inventory.attribute_names
respond_to do |format|
format.html
end
end
However, I've got the following error:
undefined method `reload!' for #<InventoriesController:0x007fccf70b7720>
If I did a reload! in console:
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"]
It works.
UPD
What I've find out is, after foing a "Inventory.reset_column_information", the attribute_names were not updated but the Class information is:
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)
So, the work around I did was:
def index
Inventory.reset_column_information
tmp = Inventory.new
@fields=tmp.attribute_names
respond_to do |format|
format.html
end
end
And finally my field in Inventory is updated.
Upvotes: 2
Views: 1861
Reputation: 2853
Though I wonder why You need this, looks very odd. But what actually You are looking is to refresh model column information. It can be done like this:
Inventory.reset_column_information
UPD
Probably it's because the class is cached. You can reload a single class by using load
load "#{Rails.root}/app/models/inventory.rb"
Though it will spit out some warning about redefining. You could use remove_const
method before actually loading again to avoid warnings.
remove_const "Inventory"
load "#{Rails.root}/app/models/inventory.rb"
But beware that doing this may cause errors in production environment. If You use several rails instances, that code would reload the class only on one! So think twice, maybe there are alternatives how to achieve what You are actually doing. I strongly not recommend going this path.
Upvotes: 2