Seeding data with Apartment gem for new schemas? - ruby-on-rails

How can I seed a new tenant in a multi-tenant app that uses the Apartment gem for scoping?
I added the following to seeds.rb but it doesn't seem to work with apartment:
tenants = Tenant.create([
{
name: 'User1',
domain: 'user1'
},
{
name: 'User2',
domain: 'user2'
}
])
Even is the database is blank, seeds.rb tries to create the schema twice and fails with this error when I do rake db:seed:
Apartment::TenantExists: The schema user1 already exists.

Rails rake runs tasks for each tenants/schemas your are trying to create. So run your creation or seeding tasks by first checking if the current schema is a public.
Something like this would do.
if Apartment::Tenant.current == 'public'
Apartment::Tenant.create('tenant1')
Apartment::Tenant.create('tenant2')
end

Related

How to resolve "not authorized for query on db.users" Mongoid

I've created a new Rails app using Rails 4 and Mongoid 4. I'm getting this error "not authorized for query on mydb.users" when I run my test:
RSpec.describe User, type: :model do
it "is invalid without a name" do
user = User.new(name: nil)
user.valid?
expect(user).to be_invalid
end
...
end
At first I thought this was an authorisation issue with Mongoid and MongoDB, but I can access mongoldb/db/collection without authenticate in the console without trouble.
Because I'm new to Rspec tests, I'm not sure the problem is with my test, mongoid or mongodb.
Any ideas?
MongoDB provide access on database level and it store on database level also. You need to provide access on this database like :
use mydb;
db.createUser(
{
user: "accountUser",
pwd: "password",
roles: [ "readWrite", "dbAdmin" ]
}
)

Validation failed on rake db:seed

I'm doing chapter 12 of hartle's tutorial. When I ran bundle exec rake db:seed I got this error:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
I try running
rake db:reset
rake db:migrate
rake db:test:prepare
And at last
rake db:populate
but they didn't solve the problem. When I run rake db:populate it gives:
Don't know how to build task 'db:populate'
This is my seeds.rb file:
# Users
User.create!(name: "Example User",
email: "example#railstutorial.org",
password: "foobar",
password_confirmation: "foobar",
admin: true,
activated: true,
activated_at: Time.zone.now)
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}#railstutorial.org"
password = "password"
User.create!(name: name,
email: email,
password: password,
password_confirmation: password,
activated: true,
activated_at: Time.zone.now)
end
# Microposts
users = User.order(:created_at).take(6)
50.times do
content = Faker::Lorem.sentence(5)
users.each { |user| user.microposts.create!(content: content) }
end
# Following relationships
users = User.all
user = users.first
following = users[2..50]
followers = users[3..40]
following.each { |followed| user.follow(followed) }
followers.each { |follower| follower.follow(user) }
I guess maybe the problem is with this line email = "example-#{n+1}#railstutorial.org"
Your problem is that rake db:reset not only drops and recreates the database, but it also migrates and seeds it as well. So essentially what's happening is this:
rake db:drop
rake db:create
rake db:schema:load # (think of this as running all the migrations you've run before)
rake db:seed # (creates your 100 database users)
and then you run:
rake db:migrate # (likely unnecessary, but it causes no harm)
rake db:test:prepare # (prepares the test database)
rake db:prepare # (runs the seeds AGAIN and causes your errors)
Obviously, from this if you just stop running the rake db:prepare command your problem will go away. However, to avoid these things in the future, I strongly recommend putting a little bit of logic in your seed file. It's just Ruby, so you could wrap the User creates in an unless statement, such as:
unless User.find_by( email: "example#railstutorial.org" )
# create all 100 users
end
This will prove to be especially valuable if you have a site on production that still uses seed data (such as a SiteSetting table); you need to make sure the data makes its way into your production database, but you'll create duplicate records (or errors) running the seed again without dropping.
As an additional reference for the answer to your question, see the selected answer to this one.
I hope this provides all the information you need!
I'm doing chapter 12 of hartle's tutorial. When I ran bundle exec rake
db:seed I got this error:
ActiveRecord::RecordInvalid: Validation failed: Email has already been
taken
When you run rake db:reset, it will seed the database for you. When you then run rake db:seed, an exception will be thrown, because you are using create! in your seeds.rb file. Unlike create, create! raises an exception when the validations fail.
You can check this by running rake db:reset, and then using rails console to check your database entries.
There are a couple things you could do to prevent this, but why would you, when your data is already there?
When I run rake db:populate it gives:
Don't know how to build task 'db:populate'
Unless you define it yourself, there is no rake task named db:populate.
try using:
if the case is already existing email it will solve it.
email = "example-#{rand(100000)}#railstutorial.org"
and you can also see errors:
user = User.new(name: "Example User",
email: "example#railstutorial.org",
password: "foobar",
password_confirmation: "foobar",
admin: true,
activated: true,
activated_at: Time.zone.now)
user.errors
user.save if user.valid
Do you have both faker and populator installed in your Gemfile? That is most likely apart of the issue. Make sure you have run:
gem install populator #From the command line
and include it in your Gemfile:
gem 'populator'
Here is a link to the Git repo https://github.com/ryanb/populator/tree/master
Great article here also: http://sudharti.github.io/articles/using-faker-and-populator-rails/

Rails convention for table with just one row

Is there any conventions of rails or a right way to create/manipulate a table that will contain just one row?
If not, what is the best way to do that?
I need a way to store configurations of the system.
Thanks.
Edited:
The rake db:seed command, basically execute whatever code you write in db/seeds.rb file of your application. Though can write any code in this file, by convention you should write code which populate your database with the basic data,
for example: when ever your deploy your application somewhere, and create a new database for it, you want that user with admin credential must be present there. So you will write the code which create that user in this file. Below is the sample code which will create a user and assign admin role to him.
puts "********Seeding Data Start************"
admin = User.create(:first_name => 'System', :last_name => 'Admin',
:email => 'systemadmin#sunpower.com', :password => 'sunpoweradmin',
:password_confirmation => 'sunpoweradmin', :source_system_id => 'systemadmin',
:source_system => 'LP',:entity_type => "Customer", :target_system => "OPENAM")
if admin.errors.blank?
puts "***User #{admin.first_name} #{admin.last_name} created ***"
admin.add_role :admin # add_role is method defined by rolify gem
puts "***admin role assigned to #{admin.first_name} #{admin.last_name}***"
else
puts "admin user failed to create due to below reasons:"
admin.errors.each do |x, y|
puts"#{x} #{y}" # x will be the field name and y will be the error on it
end
end
puts "********Seeding Data End************"
Now whenever you recreate your database, you just need to run below command to populate the database, with the basic data
$ rake db:seed RAILS_ENV=production
The correct order to setup database in production, with all the rake task available within db namespace is as below
$rake db:create RAILS_ENV=production
$rake db:migrate RAILS_ENV=production
$ rake db:seed RAILS_ENV=production
NOTE: You can replace the first two commands with $rake db:setup RAILS_ENV=production , it will run both create and migrate internally
OR
You could use the rails-settings-cached gem which is a fork of the rails-settings gem
Once setup, you'll be able to do things such as:
Setting.foo = 123
Setting.foo # returns 123
Hope this may help you or what you are looking for..

ruby-on-rails: Seeding-data strategies (or loading test data into developer database)

I want to clear and re-load my developer database (Ruby on rails) frequently.
Of course, I can manually add the data via the web page but I was wondering if anyone has any strategies for this type of testing.
(I already have unit, functional and integration tests, fyi)
Thanks
Create a seed.yml file in db directory. Add a YAML document for each model you want to create. This document should contain a list of hash. Each hash should contain model attributes.
users:
- login: jake
password: jake123
password_confirmation: jake123
first_name: Jake
last_name: Driver
- login: Jane
password: jane123
password_confirmation: jane123
first_name: Jane
last_name: McCain
categories:
products:
In your seed.rb file
seed_file = File.join(Rails.root, 'db', 'seed.yml')
config = YAML::load_file(seed_file)
User.transaction do
config.keys.each{ |key| key.classify.constantize.create(config[key]) }
end
I find it easier to modify the seed data in the YML file. Application that I have built is deployed by a different team. They like this approach too.
To clear the data I have a rake task in lib\tasks directory. I run the rake task as app:flush.
namespace :app do
desc "Flush all the seed data "
task :flush => :environment do
config = YAML::load_file(File.join(Rails.root, 'db', 'seed.yml'))
User.transaction do
config.keys.each{ |table| truncate_table(table)}
end
end
end
Time to look at "fixtures" and "seeding data" ;-) I am not good enough to give you a clear explanation, but googling those two keys should give you all you need.
Check these out: http://derekdevries.com/2009/04/13/rails-seed-data/
http://lptf.blogspot.com/2009/09/seed-data-in-rails-234.html

prepopulating admin user in database with authlogic rails plugin

I've been using the Authlogic rails plugin. Really all I am using it for is to have one admin user who can edit the site. It's not a site where people sign up accounts. I'm going to end up making the create user method restricted by an already logged in user, but of course, when I clear the DB I can't create a user, so I have to prepopulate it somehow. I tried just making a migration to put a dump of a user I created but that doesn't work and seems pretty hacky. What's the best way to handle this? It's tricky since the passwords get hashed, so I feel like I have to create one and then pull out the hashed entries...
Rails 2.3.4 adds a new feature to seed databases.
You can add in your seed in db/seed.rb file:
User.create(:username => "admin", :password => "notthis", :password_confirmation => "notthis", :email => "admin#example.com")
Then insert it with:
rake db:seed
for production or test
RAILS_ENV="production" rake db:seed
RAILS_ENV="test" rake db:seed
My favorite feature in 2.3.4 so far
If you are using >= Rails 2.3.4 the new features include a db/seeds.rb file. This is now the default file for seeding data.
In there you can simple use your models like User.create(:login=>"admin", :etc => :etc) to create your data.
With this approach rake db:setup will also seed the data as will rake db:seed if you already have the DB.
In older projects I've sometimes used a fixture (remeber to change the password straight away) with something like users.yml:
admin:
id: 1
email: admin#domain.com
login: admin
crypted_password: a4a4e4809f0a285e76bb6b35f97c9323e912adca
salt: 7e8455432de1ab5f3fE0e724b1e71500a29ab5ca
created_at: <%= Time.now.to_s :db %>
updated_at: <%= Time.now.to_s :db %>
rake db:fixtures:load FIXTURES=users
Or finally as the other guys have said you have the rake task option, hope that helps.
Most used approach is to have a rake task that is run after deployment to host with empty database.
Add a rake task:
# Add whatever fields you validate in user model
# for me only username and password
desc 'Add Admin: rake add_admin username=some_admin password=some_pass'
task :add_admin => :environment do
User.create!(:username=> ENV["username"], :password=> ENV["password"],:password_confirmation => ENV["password"])
end

Resources