Reputation: 3419
this is the first time I try to write a ruby migration script (I want to update the value of a col for a specific row).
I have a table called "events" with cols "e_id" and "e_text_en". I want to update the "e_text_en" value of the row with ID 6. In SQL it would be
update events set e_text_en = 'blabla' where e_id = 6;
My ruby approach: (20141013130000_update_broken_event_texts.rb)
class UpdateBrokenTextsEventInEvent < ActiveRecord::Migration
def Events.up
Events.where('e_id', 6).update_all(e_text_en: "blablabla")
end
end
But this gives me the error ´NameError: uninitialized constant´
rake aborted!
NameError: uninitialized constant UpdateBrokenTextsEventInEvent::Events
/var/.../20141013130000_update_broken_event_texts.rb:2:in `<class:UpdateBrokenTextsEventInEvent>'
/var/.../20141013130000_update_broken_event_texts.rb:1:in `<top (required)>'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:718:in `load_migration'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:714:in `migration'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:708:in `disable_ddl_transaction'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:1012:in `use_transaction?'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:922:in `rescue in block in migrate'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:919:in `block in migrate'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:916:in `each'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:916:in `migrate'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:764:in `up'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/migration.rb:742:in `migrate'
/var/lib/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/railties/databases.rake:42:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:migrate
While I searched for a solution I found some advises that tables are called in singular, but even when I try Event
instead of Events
I get the same error.
Can anyone help me to correct my ruby?
Versions used:
$ rails -v
Rails 4.0.1
$ gem -v
1.8.23.2
$ ruby -v
ruby 1.9.3p545 (2014-02-24) [i686-linux] Brightbox
edit: Addional infos Our Schema is created via sql-File. We started to use migrations a short time ago and this is the first update-one. The first two migrations where table-changes. We don't have any ´app/model´ files yet, becuase the other migrations worked without any, e.g.:
class AddDeliveriesToEmailQueue < ActiveRecord::Migration
def change
add_column :email_queue, :deliveries, :int, :null => false, :default => 0, :after => :error
end
end
Upvotes: 0
Views: 569
Reputation: 84124
Firstly your migration class name must match the file name (rails will load the migration file and then assume it created a class of the corresponding name). Assuming you don't change your file name, it means that you need to have
class UpdateBrokenEventTexts < ActiveRecord::Migration
...
end
Since you say that you have no model classes, you'll have to use raw SQL, for example
class UpdateBrokenEventTexts < ActiveRecord::Migration
def change
execute "UPDATE events SET e_text_en = 'blablabla'"
end
end
This is pretty much the same as using ActiveRecord::Base.connection.execute
but saves a little on the typing and makes sure Rails understands you're making an irreversible change.
Upvotes: 3
Reputation: 1037
This is a common problem when you create migration and then deside to rename it. Class name in migration should be the same as the filename. You have migration with class UpdateBrokenTextsEventInEvent
and filename 20141013130000_update_broken_event_texts.rb
, but the class name should be UpdateBrokenEventTexts
.
Upvotes: 2
Reputation: 16002
Create Event
model:
$ rails g model Event
Assuming that you have a model class Event
(inside app/models/event.rb) now, then change these lines:
class UpdateBrokenTextsEventInEvent < ActiveRecord::Migration
def Events.up
Events.where('e_id', 6).update_all(e_text_en: "blablabla")
end
end
to:
class UpdateBrokenTextsEventInEvent < ActiveRecord::Migration
def self.up
Event.where('e_id', 6).update_all(e_text_en: "blablabla")
end
end
Also, I'd recommend you to move such operations in a rake tasks instead of moving them in a migration file:
namespace :events do
desc "Update e_text_en field with blablabla"
task :update_e_text_en => :environment do
Event.where('e_id', 6).update_all(e_text_en: "blablabla")
end
end
and then from your terminal:
$ rake events:update_e_text_en
UPDATE: Don't plan to have a model class for now? No worries, you can still update the column but with a SQL query:
class UpdateBrokenTextsEventInEvent < ActiveRecord::Migration
def self.up
ActiveRecord::Base.connection.execute("UPDATE events SET e_text_en = 'blablabla'")
end
end
Please note that these actions are irreversible(since you don't know what was the previous data in the column you're updating) and that's why they shouldn't be in a migration file. You probably be better with a rake task or something for such operations.
Upvotes: 1