How to avoid loading my models in a rails Migration - ruby-on-rails

I have a rails project that uses an old versions of the FlexImage plug-in to handle images.
In the old version that image data was stored in a column called "data", in the new version that column must be named "image_file_data".
I wrote a migration to rename the column, but when I try to run the migration, my guess is that rails tries to load the models, which then automatically check to see if the valid column is there (which it isn't) and that throws an error which halts the migration.
I would guess that my problems would be solved if I never loaded the model classes in question and just wrote some sql to rename the columns. But the following line doesn't work, since rails still tries to load the model.
Apartment.connection.execute "ALTER TABLE logos CHANGE DATA image_file_data MEDIUMBLOB;"

Oops, I figured it out. I was calling
model = (table_name.to_s).classify.constantize
Earlier, and this was causing the model to load

Related

Different table name for Paper Trail?

Is it possible to specify a different table name (other than versions) for the PaperTrail gem?
In my Rails app, I already have a Versions model/table, which has nothing to do with active record versioning (my app let's uses fork a "prototype" and for better or worse I used "version" as a label for these forks). It is quite pervasive through my app, and I don't want to rename this.
When running bundle exec rails generate paper_trail:install, I get Migration already exists: create_versions.
Basically, I would like the table to be PaperTrailVersions along with the methods to access the trail to be similarly namespaced.
Any ideas? Or should I just use the Audited gem which uses a audits table?
PaperTrail supports custom version classes which can have custom table names defined.
class PostVersion < PaperTrail::Version
self.table_name = :post_versions
end
class Post < ActiveRecord::Base
has_paper_trail :class_name => 'PostVersion'
end
As of the failed generate command, I would try these steps (haven't tested them though):
You already have a migration with the name CreateVersions because you already have a versions table. That is why the generate command fails - it cannot create a migration with the same name. I think that you can simply temporarily rename the old migration (for your original versions table migration). You just need to rename the file and the classname inside the file.
Then the generate command should run. It should install a few files, their names will be printed out to the console.
Now open the newly generated create_versions migration file and rename it as well as the class name inside from CreateVersions to a name according to your custom versions table name, such as CreatePostVersions. Also rename any mention of the versions table inside it to your custom table name, e.g. post_versions.
Open all other generated migrations and change the versions table names to your custom table names inside them. There is no need to rename these files though.
Now go back to your original (and now temporarily renamed) create_versions migration file and rename it back to its original name (revert the changes on this file).
Try to run the migrations! It should work now.
The steps may seem cumbersome but they just temporarily rename the old migration to something else so that the generation command can run. Then you just need to change the table name inside the generated migration to the new table name.
The files that will be generated with the generate command can be seen here in the source code. These are the files that you'll need to modify.

Reorder/change timestamp on migration files

One of my migration files is referencing another table/model that will will be created further down the migration sequence.
Postgres doesn't like that:
PG::UndefinedTable: ERROR: relation "users" does not exist
So I wonder if there are any potential problems to manually reorder the migration files (by inventing new timestamps/prefixes)?
The affected tables are already down migrated.
When you run rake db:migrate command it compares schema_migrations table and migration files located in db/migrate folder. All the migrations which were not executed receive MigrationClass#up call then.
So starting from the point when your code is already published and/or migrations are run by other users, changing your migrations timestamps/names may lead to unprocessable migration procedure (as schema_migrations will treat a migration with changed timestamp as new, unprocessed one, and try to process it "again"). Possible workaround for this would be to comment the contents of up method for a while and uncomment it back after migrations are done. For fun you can also manipulate schema_migrations table directly from your db console (adding or removing necessary records). Both of these ways smells like a hack though.
Until then... Everything should work flawlessly.
This is what worked for me for this same situation, even though it's a hack.
Rails runs migrations in order of the timestamp, and Rails tracks which migrations have been run by the timestamp part of the migration file name, but not by the rest of the file name. So if you need to change the order of two migrations because the earlier one references the later one you can simply switch the 14 digit timestamp portion of the filenames by renaming both migration files. If the timestamp is off by even one digit Rails will think it's a new migration so write them down before changing them.

How to add a new instance variable to a class in ruby on rails using rubymine?

I have created a class using scaffold in rubymine and did db migrate. Now I need to add one more instance variable (one more column to table in db) to the same class. How do I do this using rubymine (not from command-line) without destroying the class?
I don't think I understand the real issue here.
Would you not just rollback the current migration modify the migration in db/migrate (N) and add the column you want, then update the views for the model (since you've used a scaffold)? Once you do that, you would migrate again. Either that, or you'd create a new migration that adds the column you want– however, given that you've obviously just started this app, I see no reason to add an additional migration simply for this.

Rails 3 - Foreign Keys - Strings vs Symbols

I am in the process of learning Rails and I've ran into an interesting problem tonight.
I was creating a migration that would require an index on the foreign key:
Whenever I would run 'bundle exec rake db:migrate', I would receive this console error:
It looks as if it was trying to create the index before it was creating the reference.
The reason I believe this is because when I change the "subject" reference to a symbol:
The migration then suddenly works as expected!
This may just be the fact that I'm a total newby, but are symbols actually processed faster by Ruby than strings are?
Just curious - thanks!
This isn't a "faster" problem, or a problem of speed. The migrations are executed one line at a time, in order. The way you had it specified before simply didn't create the column correctly, hence when it got to the line where you create the index, the names didn't match up.
My guess is, with the string version it created the column name exactly as you spelled it, "subject" as opposed to subject_id when you use a symbol. Either way, you definitely had a name mismatch between when the column was created, and when the index was being built.
Always use symbols for this in your migrations, and you should be fine. Always check your schema.rb file, or browse the database using a GUI tool, after a migration to make sure the columns got created the way you expect, and with the data types you think they are, and you should be good.

rake db:migrate running all migrations correctly

I'm fairly new to Ruby on Rails here.
I have 2 migrate files that were provided. The first one, prefixed with 001, creates a table and some columns for that table. The next migrate file, prefixed with 002, inserts rows into the table created in file 001.
Running the migration (rake db:migrate in command line) correctly creates the table but doesn't insert any of the data which is the problem. The code from the insertion looks like this (except with a lot more Student.create statements,
class AddStudentData < ActiveRecord::Migration
def self.up
...
Student.create(:name => "Yhi, Manfredo", :gender => "M")
...
end
def self.down
Student.delete_all
end
end
My understanding is that Student is a model object, so my Student model looks like this,
class Student < ActiveRecord::Base
end
Do I need to explicitly define a create method in Student or is that something that's given? (This project was made using scaffold)
Thanks.
Edit 1: I used Damien's suggestion and called create! instead of create but got the same response. Then what I did to see whether the code was even reaching that far was call this,
Student.create12312313!(:name => "foo", :gender => "M")
which is obviously invalid code and the migrate didn't throw any error.
Edit2: Answer found. The schema_migrations table had its version set to 3, and I only had 3 different migration files so it never ran any of the migration files I had. That's why nothing was ever updating, and the bogus creates I used were never throwing errors. The reason the student data wasn't inserted the first time was because a certain table was already in the database and it caused a conflict the first time I migrated. So what I was really looking for wasn't db:migrate but rather db:reset Several hours well spent.
The create method is inherited from ActiveRecord::Base.
So no, you don't need to define it.
One reason why your datas could not be included would be that you have validations that doesn't pass.
You can easily see the error making your datas not being included by using create! instead of create.
So if the model can't be created, an exception will be thrown and the migrations will fail.
You may want to look at Data Seeding in rails 2.3.4. And is your rails migrations really running 001_create_whatever.rb? or were you just using that as an example? since 2.2.2 (iirc) migrations have been using timestamps such as 10092009....create_whatever.rb
How old is your rails version?
The migrations won't run if their schema number is in the database.
For older versions of rails, there will be a single row with the highest migration performed in it.
For newer versions, every migration gets a unique time-stamp as its version number, and its own row in schema_migrations when it gets added.

Resources