Rails - where to put files that are not part of the deployment - ruby-on-rails

I have to do a lot of conditioning of the data that will seed my rails database. This is a one-shot activity before deployment, never used after deployment, but I want to keep the programs I use for it within the projects configuration management (mainly for the sake of an audit trail for where the seed data came from).
Where is the canonical place in a Rails app for such support files that don't form part of the application?

Seed data should go in db/seed.rb. You can learn more about seed data in the docs.

The problem with adding all these items to your repository is that not only will it make the checked in code large, also you will have to clean the code each time after deploy.
I do not think such items should be checked in. Personally, I place all such items in public data, upload it for first deploy and then next deploy will no longer have this folder as the deployment using capistrano will not link to the data folder anymore.
This way the data can stay in the shared folder on the server should you need it again but not in your repository.

Related

Any gotchas running a Rails installation after repeatedly copying it?

My basic question is: if I repeatedly copy a Rails app, so there are many generations of the same repo (i.e., various iterations of a Rails app's directory and files), what do I need to do to ensure that the server runs normally and avoid major issues?
I'm writing a learning app that drills the user on programming tasks. Right now it supports only single-file tasks. I want to add support for multiple-file tasks next, involving HTML/CSS/JS and Rails tasks (e.g., "add a model that does such-and-such" or "add a Minitest test for such-and-such feature"). The user will be required to edit the Rails code directly, and my app will then automatically run the server and show the results. After each question is answered (i.e., each task is performed), my app will migrate down the database automatically as necessary and copy the repo anew from a tarball--basically, preparing the stage for the next time the user tackles the task. (Well, I hope it's a good idea.)
Since Rails apps are so big and complex, of course it's not feasible to build and add a separate Rails app for every question. Instead, I will have many questions/tasks that are based on the same repo (installation). After each question is answered (i.e., each task is performed), the database will be migrated down as necessary and the repo copied anew from a tarball. So far, so good? (I anticipate problems using Git to do this...so I would just use Minitar for this.)
But of course I will have to make other versions of the same repo (using the same database, or maybe a copy) when I make other clusters of questions. For example, I might want a bunch of questions/tasks related to using AJAX in Rails, and for that I need to prep an installation in various ways. But if I'm just building on a copy of a previous repo that has its own tasks, will the copying process cause issues for the later repo and its tasks?
I have done some testing. I have already confirmed that if I simply execute cp -r repo1/ repo2/ and then run rails s in repo2, the server for the latter starts normally. While data written in repo2 does not appear in repo1, I can't create an identically-named model (which is a little puzzling). I imagine this might be a problem for some questions--i.e., I don't really want them running from one and the same database for all repos, even if later database versions are based on earlier versions. So whenever I copy a repo, I guess I'll want to make a copy of the database as explained here. Sound right?
Is there anything else I'd need to do in building this feature that would prevent issues related to repeatedly copying different iterations of the same repo (and database)?
I think you're making it more complicated than it needs to be. This can all be done in git by leveraging git feature branches, e.g. question-1, question-2, for each derivation and combining that with the rails rake database tasks, e.g. rake db:drop, rake db:create, rake
db:migrate, rake db:seed, to ensure your database is bootstrapped properly for each branch.
An alternative approach could be to add SQL dumps of your final database state to each feature branches and load them via a rake task to bootstrap your database to your desired state.

ruby on rails - git repository, database handling

I am currently using Bitbucket and am handling a Ruby on Rails repository across users. By default, when one user pushes the repository(default command - git push origin master -entire rails folder), I assume that the db also gets pushed to bit bucket, right?
When a second user downloads the repository off git, shouldn't i expect all the db files to also get downloaded?
Is it necessary for the second user to run rake db migrate commands again after downloading the file?
In the specific case above, I am the second user and I get the following error message upon downloading the repository off BitBucket, while the file run perfectly on the uploaders computer:
ActiveRecord::StatementInvalid in StaticPagesController#home
Could not find table 'users'
I want to make sure that both of us are working on the same DB and are not working in parallel on different datasets.
Data in your database will reside only in database. It will not be in git repository. The repository contains database config files and migration files to create databases on the fly. Again, it doesn't contain data.
If you want to work on the same database, I would look into using Amazon AWS RDS. Setting up RDS is not undoable, but it's not trivial enough for me to expound on exactly how you do that here.
I guess you are new to Rails. The way Rails handle database in development is :
with database structure:
You maintain the structure through migrations file.
Yes, if you pull new code that does contain new migration file, you
need to run rake db:migrate. You will notified if you don't.
with database data:
In development, you can maintain data to test through seed file. You can watch this great screencast here: http://railscasts.com/episodes/179-seed-data
Better, you should use seed_fu gem https://github.com/mbleigh/seed-fu

Storing Rails app version in database

Is storing version of Rails application in database is the right way ? Rails version it's a release production code version incremented every time we are doing deployment. It used for informational purposes only. Generally people recommended setting up version in config/initializers/version.rb but IMO it could be hard for change automatically during deployment (adding file to .gitignore or not and etc.) Using AR record we could easily had ApplicationVersion.last.to_version in our code. What do You thing about this ?
How about writing it out to a yaml file that you could generate during deployment? It'd be a simple matter to generate that during deployment, especially if you're using a tool such as capistrano.
My concern about writing it to a file is that the production database isn't a concrete resource. What if you have a crash and need to restore the database? The database potentially will report a different version than the current state of the code.

What are the dangers of using EF Migrations (or any auto-migration framework) in production?

I'm considering using Entity Framework 4.3 migrations in a production site. The following is my concern:
If the migration fails for whatever reason, I want all statements
rolled back and the site placed in a down state so no users can use
the site while I try to fix the problem. The only thing is I can't
fall back to executing the scripts by hand against the database since
migration files are compiled in the assembly. I could keep track of
both migration files and sql script files separately but at that point why use
migrations at all.
At work, script files are stored in a SQL folder (that no one can browse to) on the site. Previously run script files are registered in the database. When new script files appear in the folder (and aren't in the database), if a user is an admin, they'll be redirected to a DB portal, else get a site-down-for-maintenance. If we try and fail to execute any scripts from the portal, we grab the new scripts and try to run them manual inside of express studio. This has worked for over a decade. I'm only exploring migrations to see if a better way has arrived. It doesn't feel like it. Please let me know if there's a better way and if it's not Migrations, what is it.
I would definitely not use automatic migrations in a production environment. In fact, I'm too much of a control freak to use automatic migrations at all. I prefer code based migrations to ensure that all databases (developers' own personal, test environment, production) have gone through exactly the same update sequence.
Using code-based migrations where each migration step gets a name, a separate migration script can be generated for use when lifting test and prod environments. Preferably it should be run on a copy of the database to validate before running on the real prod environment.
Added Later
To prevent EF Migrations from doing anything automatic at all, a custom initializer strategy can be used. See my blog or the Deploying EF Code First Apps to Production Database Stack Overflow question.

Should I use migrations to create folders?

I created a feature that requires two folders to work correctly. These folders didn't existed in the rails project so I had to create them. Now I need to push this functionality so that the other developers can use it as well.
What do you think is the best practice:
Create the folders locally and leave a note somewhere explaining that these folders needs to be created
Create a migration that will create these folders
Create the folders if they don't exist on execution
So what are the best practices regarding this?
Two choices
1. Put them under version control.
When the developers next check out the folders will get created. How you add them to VC depends on the nature of the tool you're using but many tools require that the directories contain a file (possibly hidden).
That works great if the folders are in the source tree. You also have the potential on a Unix-like os to soft-link from within the source tree to a well known location outside of the source tree. Depending on the VC system (we use Mercurial), you can make the soft link a versioned item.
2. Create them as your process starts
If you're going to do this, you might as well go the extra mile and make their location a configurable option. On start up, read the config file, make the folders and continue.
I would think that as part of the dev builds there must be rake tasks that get invoked to do certain activities; it would be appropriate to either include such activity in a rake tasks where it fits most appropriately.
It should check for folders and if it doesn't exists; just create them. Migrations for creating folder is really not the right way I guess.
I'd include this in a bootstrap rake task.
This is a good question.
For me I would put the folder creation in the migration if and only if the folder was required as part of that migration. So for instance you were adding or updating the table dealing with attachments (such as with attachment_fu etc), then I would consider putting the directory creation/deletion in there.
However creating directories is an environment specific thing (different on Windows vs *nix etc), especially where permissions are involved. Therefore it would make sense to go where these issues are handled in an environment-abstracted way. Perhaps in the deployment script (if using Capistrano) or as other people have suggested in a rake task.
I'll add them to the repository. Maybe if it holds temporary data I'll ignore the contents.

Resources