Adding sample data to database using rake for a rails engine - ruby-on-rails

I am trying out Rails engines by creating a classifieds engine where users can view/post/reply to classifieds.
The main application contains code for user authentication and profiles while there is an engine which I have created which will deal with the classifieds functionality.
Now I want to add some sample data to the database for the classifieds engine. So I created a rake file called 'sample_classifieds_data.rake' in 'vendor/plugins/classifieds/lib/tasks' and I added the yml files in 'vendor/plugins/classifieds/lib/tasks/sample_classifieds_data'
The code of the rake file and a sample yml file can be found here: http://gist.github.com/216776
Now the problem is that when I run the rake task, no error is being thrown but the values are not getting populated in the database.
Any ideas? BTW, it is development environment and the database is the development database.
I ran a similar rake task to populate sample users in the database which worked. the location of that rake file 'sample_data.rake' was located in 'lib/tasks'.

In rails edge, you can use the rake db:seed feature to add datas to your base. See the commit.
The use is pretty simple.
Create a db/seeds.rb file.
And put whatever code you want to seed your database in it.
For example :
Category.create!(:name => 'My Category')
Country.create!(:name => 'Cassoulet Land')
And when you want to seed your database, you could do a rake db:seed
If, for any reason, you do not wish to use edge (which would be comprehensible in a production environment), you can use the Seed Fu plugin, which quite does the trick for you.

Your task looks good. About the only thing would cause your task to fail silently is that the file you're passing to Fixture.new does not point to a yml or csv file.
Double check by modifying the put statement to print the full path of the file it imported, and compare what it prints against your directory structure.
For example, things will fail silently if your fixture files start with a capital letter? Categories.yml instead of categories.yml

The db:seed task was added in Rails 2.3.4. So no need to run edge.
http://weblog.rubyonrails.org/2009/9/4/ruby-on-rails-2-3-4

Related

Where do I put seed data if I have already created my database in my Rails project?

I’m using Rials 4.2.5. I want to create some seed data for a new model, user_images, I just created in an existing project. However, I already have a db/seeds.rb file that has been run on my database. Where do I put the seed data for this new model? I assume i can’t use db/seeds.rb because it has already been run. It is not an option to blow away the database and start again.
Thanks, - Dave
You can use seeds.. I use, for example:
Person.find_or_create_by(name: 'Bob')
Lots of them, as required, then run as many times as I like.. I run seeds on each auto deployment for example, so I don't forget..
Link to command: http://apidock.com/rails/v4.2.1/ActiveRecord/Relation/find_or_create_by
create a custom rake task in lib/tasks. The file should end in .rake. Then you run it by the name. For example:
task :do_something => :environment do
p "do something"
end
You'd run this task by calling rake do_something in terminal.

Rails separated seeds

Hi i probably have a simple question.
I have this database with moodboard templates.
I want to transport it to the server with capistrano but in my seeds.rb file there is only all the seeds and if i run them again a lot of data gets inserted twice.
I normally run:
rake db:seed
But i would like to see another command
How can i make a separate seed file to execute on its own.
You can either delete your seeds before insert in seeds.rb or check the count of the model rows or check for the id if the item you're looking to insert before you insert it in your seeds.rb. Basically, I think you just need to add some checks before you insert additional data. I could provide a more specific answer if you posted your seeds.rb.

Regenerate ERD after rake db:migrate

I am using http://rails-erd.rubyforge.org/ to generate an ERD - the output is a very nice diagram of my project's object model. There is also a rake task to generate the ERD, generate_erd, that I would like to have invoked automatically after I run rake db:migrate. How do I do that?
The given link by #MaxWilliams is a helpful but I don't think any of those answers quite do what you want. I found this article on Rake Task Overwriting. It's from 2008, but I tried this out and it worked.
I created another .rake file (for organization) and just happened to call mine migrate_and_generate_erb.rake but name it whatever you want.
Inside I just had this:
namespace :db do
task :migrate do
Rake::Task["erd"].invoke
end
end
Basically, according to the article, Rake just keeps appending code implementation to the task if it's already defined.
Now running rake db:migrate also generated me my ERD.
Careful: You'll also want to do the same for db:rollback so that rolling back a migration also updates your ERD.
One last note: consider also just aliasing this (shell command), just in case you'd ever want to run the migrate without generate the ERD, or use environment variables along with your new Rake task.

Populate a constant values table

In a Rails application, I need a table in my database to contain constant data.
This table content is not intended to change for the moment but I do not want to put the content in the code, to be able to change it whenever needed.
I tried filling this table in the migration that created it, but this does not seem to work with the test environment and breaks my unit tests. In test environment, my model is never able to return any value while it is ok in my development environment.
Is there a way to fill that database correctly even in test environment ? Is there another way of handling these kind of data that should not be in code ?
edit
Thanks all for your answers and especially Vlad R for explaining the problem.
I now understand why my data are not loaded in test. This is because the test environment uses the db:load rake command which directly loads the schema instead of running the migrations. Having put my values in the migration only and not in the schema, these values are not loaded for test.
What you are probably observing is that the test framework is not running the migrations (db:migrate), but loading db/schema.rb directly (db:load) instead.
You have two options:
continue to use the migration for production and development; for the test environment, add your constant data to the corresponding yml files in db/fixtures
leave the existing db/fixtures files untouched, and create another set of yml files (containing the constant data) in the same vein as db/fixtures, but usable by both test and production/development environments when doing a rake db:load schema initialization
To cover those scenarios that use db:load (instead of db:migrate - e.g. test, bringing up a new database on a new development machine using the faster db:load instead of db:migrate, etc.) is create a drop-in rakefile in RAILS_APP/lib/tasks to augment the db:load task by loading your constant intialization data from "seed" yml files (one for each model) into the database.
Use the db:seed rake task as an example. Put your seed data in db/seeds/.yml
#the command is: rake:db:load
namespace :db do
desc 'Initialize data from YAML.'
task :load => :environment do
require 'active_record/fixtures'
Dir.glob(RAILS_ROOT + '/db/seeds/*.yml').each do |file|
Fixtures.create_fixtures('db/seeds', File.basename(file, '.*'))
end
end
end
To cover the incremental scenarios (db:migrate), define one migration that does the same thing as the task defined above.
If your seed data ever changes, you will need to add another migration to remove the old seed data and load the new one instead, which may be non-trivial in case of foreign-key dependencies etc.
Take a look at my article on loading seed data.
There's a number of ways to do this. I like a rake task called db:populate which lets you specify your fixed data in normal ActiveRecord create statements. For getting the data into tests, I've just be loading this populate file in my test_helper. However, I think I am going to switch to a test database that already has the seed data populated.
There's also plugin called SeedFu that helps with this problem.
Whatever you do, I recommend against using fixtures for this, because they don't validate your data, so it's very easy to create invalid records.

Ruby on Rails Migration - Create New Database Schema

I have a migration that runs an SQL script to create a new Postgres schema. When creating a new database in Postgres by default it creates a schema called 'public', which is the main schema we use. The migration to create the new database schema seems to be working fine, however the problem occurs after the migration has run, when rails tries to update the 'schema_info' table that it relies on it says that it does not exist, as if it is looking for it in the new database schema and not the default 'public' schema where the table actually is.
Does anybody know how I can tell rails to look at the 'public' schema for this table?
Example of SQL being executed: ~
CREATE SCHEMA new_schema;
COMMENT ON SCHEMA new_schema IS 'this is the new Postgres database schema to sit along side the "public" schema';
-- various tables, triggers and functions created in new_schema
Error being thrown: ~
RuntimeError: ERROR C42P01 Mrelation "schema_info" does not exist
L221 RRangeVarGetRelid: UPDATE schema_info SET version = ??
Thanks for your help
Chris Knight
Well that depends what your migration looks like, what your database.yml looks like and what exactly you are trying to attempt. Anyway more information is needed change the names if you have to and post an example database.yml and the migration. does the migration change the search_path for the adapter for example ?
But know that in general rails and postgresql schemas don't work well together (yet?).
There are a few places which have problems. Try and build and app that uses only one pg database with 2 non-default schemas one for dev and one for test and tell me about it. (from thefollowing I can already tell you that you will get burned)
Maybe it was fixed since the last time I played with it but when I see http://rails.lighthouseapp.com/projects/8994/tickets/390-postgres-adapter-quotes-table-name-breaks-when-non-default-schema-is-used or this http://rails.lighthouseapp.com/projects/8994/tickets/918-postgresql-tables-not-generating-correct-schema-list or this in postgresql_adapter.rb
# Drops a PostgreSQL database
#
# Example:
# drop_database 'matt_development'
def drop_database(name) #:nodoc:
execute "DROP DATABASE IF EXISTS #{name}"
end
(yes this is wrong if you use the same database with different schemas for both dev and test, this would drop both databases each time you run the unit tests !)
I actually started writing patches. the first one was for the indexes methods in the adapter which didn't care about the search_path ending up with duplicated indexes in some conditions, then I started getting hurt by the rest and ended up abandonning the idea of using schemas: I wanted to get my app done and I didn't have the extra time needed to fix the problems I had using schemas.
I'm not sure I understand what you're asking exactly, but, rake will be expecting to update the version of the Rails schema into the schema_info table. Check your database.yml config file, this is where rake will be looking to find the table to update.
Is it a possibility that you are migrating to a new Postgres schema and rake is still pointing to the old one? I'm not sure then that a standard Rails migration is what you need. It might be best to create your own rake task instead.
Edit: If you're referencing two different databases or Postgres schemas, Rails doesn't support this in standard migrations. Rails assumes one database, so migrations from one database to another is usually not possible. When you run "rake db:migrate" it actually looks at the RAILS_ENV environment variable to find the correct entry in database.yml. If rake starts the migration looking at the "development" environment and database config from database.yml, it will expect to update to this environment at the end of the migration.
So, you'll probably need to do this from outside the Rails stack as you can't reference two databases at the same time within Rails. There are attempts at plugins to allow this, but they're majorly hacky and don't work properly.
You can use pg_power. It provides additional DSL for migration to create PostgreSQL schemas and not only.

Resources