How best to create table on initialization? - ruby-on-rails

Happy New Year everyone.
In my Rails 4 application I have a table plans containing the records for the plans that a user can subscribe to.
It is absolutely paramount for the app that this table is populated at any time, in development, test, and production mode. Otherwise the app will not work.
What is the best way to create those records?
Should I put a create method into an initializer? Or set up a rake task and run it manually whenever I restart the server (sounds a bit cumbersome, though)?
Thanks for any help in this matter.

Rails has a 'seeds' feature that should be used for seeding a database with initial data.
It's a really simple feature: just fill up db/seeds.rb with some Ruby code, and run rake db:seed
source: http://edgeguides.rubyonrails.org/active_record_migrations.html#migrations-and-seed-data
If you want to use data in your test environment, you might also be interested in using fixtures for your plans. Take a look at http://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures

Related

Ruby on Rails database workflow

I'm a bit of a Rails beginner, so I'm sorry if this question is easy. I'm wondering how I am supposed to modify the Rails database as a developer without letting users of the site modify data.
More information:
Let's say I am trying to create a website that lists books along with their information. I want users to be able to see these books, but not add/delete them. As a developer, I want a way to add books without using the command line (hard to edit mistakes). What's the easiest way for me to do this? Would there be any differences between the development database and a live hosted one?
I think there are a few approaches to do this.
different user roles. This technically breaks the rule of without letting users of the site modify data, but being able to differentiate between normal and admin users means you can limit who actually can add data into the database. I used cancancan as a way to authorize requests but I know there are others.
I agree doing it using the command line isn't ideal, but rails do support rake tasks. You can create a task that will handle most of the logic and all you need to do is something like
rake create_book["name here"]
This will make the process less error-prone.
Create data using rails migrations. Rails can generate the skeleton file for you, and you just ran any ActiveRecord methods. However, the main purpose of migration is to update the database schema, but they can seed the database as well. here's the example from the dcos
Would there be any differences between the development database and a live-hosted one?
Yea, they should be totally separate database instances. You don't want to have your development database be the same as the live one. This would cause major problems. Rails have a concept of environments where you can use different configurations, so you can pick and choose what database URL to use.
like #davidhu said here The best approach really is the use of authorization. If only admin can see a page to CRUD the books then you don't have to worry about normal users doing same plus it makes it easy for you as the admin to make changes or add to the collection. Add the gem (or reinvent the wheel) then Rails will take care of the rest for you.

Where should I create static records in Rails?

In my application, I have users and roles. Some of the roles should always exist, such as "Admin". Where should I do something like:
Role.create(name: 'Admin')
In the past, I've always placed these lines in a migration to ensure it ends up on the deployed server. This sometimes leads to issues as a developer may forget to instead write it like:
Role.where(name: 'Admin').first_or_create
Should they go in the seeds.rb file? I have generally used the seeds file for local development "playing around" data.
What is the Rails Best Practice for generating static data?
The seed.rb is the perfect place for that. Migrations are not meant to be used for anything other than convenience during development and should never be relied upon for really anything.
From the docs:
To add initial data after a database is created, Rails has a built-in
'seeds' feature that makes the process quick and easy. This is
especially useful when reloading the database frequently in
development and test environments. It's easy to get started with this
feature: just fill up db/seeds.rb with some Ruby code, and run rails
db:seed
http://edgeguides.rubyonrails.org/active_record_migrations.html#migrations-and-seed-data
Rails way is to use seeds.rb - simple and useful.
In my opinion, data migrations are needed only in situations when you must add data to existing records (after inserting new column with default value, for example)

Rails: best way to start an app with multiples models

I want to create a Rails app but I have a question before start it.
I have defined a database model in paper (about 15 tables) and I don't know which is the best way to start the application:
Create the tables on database with my database client and after that in console do:
rake db:schema:dump
with this I will obtain the shema.rb and after that do a :
rake db:migrate
or
In console, one to one, create the models, edit them with an editor and do:
rake db:migrate
I think the first one is more quickly but the second I think is better from the point of view of rails.
I am bit confused about that, can anyone help me with this question?
Rails mean the only sure way to create a database for a new application - migration.
You can create a single migration for all of your application but such migration is not easy to roll back.
Therefore wise to create a migration for each table.
Normal situation when you have 100,500 migrations in the end. For that you get your application is ready for deploy to combat server.
Permitted the creation of migration through model and scaffold or independently.
Why not use a generator?
rails g model User first_name last_name age:integer email user_name
You don't need to specify type if it's string. This will generate model class and migration.
I think there may be varying viewpoints on this issue.
Also, it depends if you're using the rails built-in sqlite database.
However, assuming that you do use the default rails db configurations,
I personally prefer the second choice.
Later, you might want to change some parts in your tables.
If you follow the rails way of doing so, this process will be very easy and less confusing.
Also, you can always add custom ruby scripts for pre-loading with data.
Of course, other people might find the other way easier.

What's the best method for creating "test" database content in >= Rails 3.2.0?

I want to be able to create a few dozen users, articles (or whatever resources are unique to the app), etc to see how the app looks and responds when full. This is just for testing/dev purposes, so I want to be able to roll it back, destroy it, or whatever easily. Perhaps I'm overthinking it, who knows.
I've seen people recommend just using a standard migration, which is one idea, but I want to do this OPTIONALLY, I don't want everyone on the project to get the sample content as they update the app.
Other people have mentioned Factory Girl, but that looks like it might be either overkill or a side-use of a gem really designed for testing, etc. It wasn't perfectly clear.
So what do you all do in this case?
I recommend a rake task. You can stick it in lib/tasks and so everyone in the project gets it, but not everyone needs to run it, and only when it's run will it do anything. This a great tutorial on writing rake tasks, just remember to read the part under the Rails heading in order to learn how to bring in your models.
After that, your rake tasks is basically just ruby code. I'd suggest using the dynamic find_or_create_by methods in order to explicitly create the models you want, and if it's run multiple times, they won't be created multiple times. You can also choose to destroy all records in a particular model before creating them.
I wouldn't recommend using Factory Girl because you probably want explicit control over how your models are created.
Here's an example rake task to show how easy it is:
#lib/tasks/my_task.rake
task :fake_data => :environment do
MyModel.find_or_create_by_name("Test")
end
Then in your console:
rake fake_data
Or:
rake fake_data RAILS_ENV=test
Ta da!
Take a look at Rails seed data features
http://railscasts.com/episodes/179-seed-data

What's a good way to handle data across Prod, Dev, Test DB's in Rails 3 (using Cucumber)?

I have a small Rails 3 app (you have a listing with photos, and prices), and am trying to get into Cucumber BDD testing.
I have 2 types of Database data:
1)
There's consistent data (like a table of price ranges) that needs to be the same across my Prod, Dev, and Test servers.
2)
Then there's the other data that can change from each environment (like usernames, listing data etc). I just need to make sure I have a good spread of data in my dev and test servers that matches data that should / would be in prod.
I have 2 questions.
First:
What's the best way to handle data like this? How can I ensure consistency across the different environments in a painless way?
Second:
I'm using fixtures to populate my dev db. I'm having a hard time populating my test DB. What's the best way to populate the test DB (while using Cucumber) so I can run through my scenarios?
as suggested, db/seeds can be used for some use cases, you can also checkout this solution: http://jedschneider.posterous.com/using-semi-static-data-as-an-activerecord-mod that may address other use cases.
In regards to cucumber, the true cucumber philosophy would be to create a resource through the web interface, eg to create a user: go to user sign in, register, sign in as that user. They discourage direct model access (page 292 ish), but it is too convenient to not do, in my opinion, as long as the web interface workflow is also tested.
For this, I prefer using factories over fixtures as they are less fragile in on-going development. I would recommend factory_girl or factory_girl_rails for Rails 3. Thus you can have a step definition:
/Given a valid user exists?/ do
#user = Factory(:user)
end
which populates the user table with a user an creates an instance variable that you can use to follow through the scenario with. If you want to use fixtures with cucumber, setup a before hook that will load your fixtures for you.
https://github.com/rails/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb
The idea behind db/seeds.rb is for that kind of data that is pretty much static and needs to be universal. Anything in that file will be pulled in during db:setup, and can be added manually with rake db:seed
second question should be straight forward, rake db:fixtures:load should not be dependant on enviornment. So you should be able to do something like RAILS_ENV=test rake db:fixtures:load and that should load up your test database with your fixture data.

Resources