How to repeat single hash multiple times in one array? - ruby-on-rails

I want to create dozens of logins that rely on data from this array, logins:
logins = [
{
email: Faker::Internet.email,
password: "password",
first_name: Faker::Name.first_name,
last_name: Faker::Name.last_name
},
{
email: Faker::Internet.email,
password: "password",
first_name: Faker::Name.first_name,
last_name: Faker::Name.last_name
}
]
What is a better way of writing this array rather than copy and pasting that hash dozens of times? I am familiar with x.times do but that wouldn't work on an array.
Here's the code where I pass in the logins:
logins.each do |login|
li = LoginInformation.new(login: login[:email], password: login[:password])
if UserManager.save(li)
company_ids.each do |id|
li.contacts.create(first_name: login[:first_name], last_name: login[:last_name], email_address: login[:email], company_id: id, is_employee: true)
end
end
end

One way to simplify the creation of your logins array is to pass the hash object with the included Faker methods as a block, like so:
logins = Array.new(10) { { email: Faker::Internet.email, password: 'password', first_name: Faker::Name.first_name, last_name: Faker::Name.last_name } }
You can replace the 10 in this example with the number of elements required for your use case.
Hope this helps!

.times returns an enumerator that you can call .map on to get an array.
logins = 10.times.map do
{
email: Faker::Internet.email,
password: "password",
first_name: Faker::Name.first_name,
last_name: Faker::Name.last_name
}
end
Or use Array.new as mentioned by Zoran Pesic.

You can use for loop to insert the values multiple times
logins=[]
for i in 0..10
logins <<
{
email: Faker::Internet.email,
password: "password",
first_name: Faker::Name.first_name,
last_name: Faker::Name.last_name
}
end

Can do this way also:
10.times do
login = { email: Faker::Internet.email, password: 'password', first_name: Faker::Name.first_name, last_name: Faker::Name.last_name }
li = LoginInformation.new(login: login[:email], password: login[:password])
if UserManager.save(li)
company_ids.each do |id|
li.contacts.create(first_name: login[:first_name], last_name: login[:last_name], email_address: login[:email], company_id: id, is_employee: true)
end
end
end

Related

Seeding with has_one relationship, Ruby on Rails (edited)

I try to seed data for my app. I managed to do this, but the code is ugly, and it possibly can be a lot easier. I;m a complete beginner so I would be grateful for any help. I had to create one profile and one todolist for each user, and 5 todoitems for each todolist.
user1 = User.create!( username: "Fiorina", password_digest: "123456")
profile1 = user1.create_profile(gender: "female", first_name: "Carly", last_name: "Fiorina", birth_year: 1954)
todolist1 = user1.todo_lists.create(list_name:"List1", list_due_date:Date.today + 1.year)
user2 = User.create!( username: "Trump", password_digest: "123456")
profile2 = user2.create_profile( gender: "male", first_name: "Donald", last_name: "Trump", birth_year: 1946)
todolist2 = user2.todo_lists.create(list_name:"List2", list_due_date:Date.today + 1.year)
user3 = User.create!( username: "Carson", password_digest: "123456")
profile3 = user3.create_profile( gender: "male", first_name: "Ben", last_name: "Carson", birth_year: 1951)
todolist3 = user3.todo_lists.create(list_name:"List3", list_due_date:Date.today + 1.year)
user4 = User.create!( username: "Clinton", password_digest: "123456")
profile4 = user4.create_profile( gender: "female", first_name: "Hillary", last_name: "Clinton", birth_year: 1947)
todolist4 = user4.todo_lists.create(list_name:"List4", list_due_date:Date.today + 1.year)
for i in 0..4
todolist1.todo_items.create(due_date: Date.today + 1.year, title: "TodoItem1", description: "Opis", completed: 1)
end
for i in 0..4
todolist2.todo_items.create(due_date: Date.today + 1.year, title: "TodoItem2", description: "Opis", completed: 1)
end
for i in 0..4
todolist3.todo_items.create(due_date: Date.today + 1.year, title: "TodoItem3", description: "Opis", completed: 1)
end
for i in 0..4
todolist4.todo_items.create(due_date: Date.today + 1.year, title: "TodoItem4", description: "Opis", completed: 1)
end
DRY it (don't repeat yourself):
[
{last_name:'Fiorina', first_name:'Carly', gender:'female', birth_year:1954},
{last_name:'Trump', first_name:'Donald', gender:'male', birth_year:1946},
{last_name:'Carson', first_name:'Ben', gender:'male', birth_year:1951},
{last_name:'Clinton', first_name:'Hillary', gender:'female', birth_year:1947},
].each_with_index do |p, index|
user = User.create!( username: p[:last_name], password_digest: "123456")
profile = user.create_profile(p) # note that p only has fields for profile attributes
todolist = user.create_todo_list(list_name:"List#{index+1}", list_due_date:Date.today + 1.year)
5.times.each{|i|
todolist.create_todo_item(due_date: Date.today + 1.year, title: "TodoItem#{i+1}", description: "Opis", completed: 1)
}
end
Hey you can build_profile for has_one relation ship and used todo_lists.build for has_many try this way
User.create!( username: "Fiorina", password_digest: "123456").build_profile(gender: "female", first_name: "Carly", last_name: "Fiorina", birth_year: 1954).save!
for has_many relation ship
User.create!( username: "Fiorina", password_digest: "123456").todo_lists.build().save!

get parent id on a nested attribute in rake seed

I'm trying to setup my seed like this:
company = Company.create!( name: 'Hirthe-Ritchie',
time_zone: 'Stockholm',
users_attributes: [{
first_name: 'Demo',
last_name: 'Memo',
title: 'CEO',
email: 'demo#demo.com',
time_zone: 'Stockholm',
admin: true,
password: 'foobar',
activated: true,
activated_at: Time.zone.now,
reviewer_attributes: {
reviewer_user_id: # parent id
}
}]
)
now what I want is that on reviewer_attributes, to make reviewer_used_id, the user id of the user being created.
So I have user_id and reviewer_user_id in my Reviewer model, now how do I get the parent's id in a nested attribute like I have here?
You will have to split your code into several new/create between the related objects. Try the following:
user_attrs = {
first_name: 'Demo',
last_name: 'Memo',
title: 'CEO',
email: 'demo#demo.com',
time_zone: 'Stockholm',
admin: true,
password: 'foobar',
activated: true,
activated_at: Time.zone.now
}
user = User.new(user_attrs)
user.reviewer = user
company = Company.new(name: 'Hirthe-Ritchie', time_zone: 'Stockholm')
company.users << user
company.save!

Db doesn't seed: how to determine the cause?

None of the data in seeds.rb is loaded into the development db. There is no error message. How can I determine the cause?
If I run rake:db:migrate:reset it just runs and produces no error messages. The if I go to the console, run User.first, it says nil. Also I downloaded the development db and there are no records in it (tables are created correctly, just no records).
Is there some way to trace the cause?
Part of seeds.rb:
User.create!(fullname: "Example User",
username: "fakename0",
email: "example#railstutorial.org",
admin: true,
activated: true,
activated_at: Time.zone.now,
password: "foobar",
password_confirmation: "foobar")
User.create!(fullname: "Example User 2",
username: "fawwkename0",
email: "exaaample#railstutorial.org",
admin: false,
activated: true,
activated_at: Time.zone.now,
password: "foobar",
password_confirmation: "foobar")
99.times do |n|
fullname = Faker::Name.name
username = "fakename#{n+1}"
email = "example-#{n+1}#railstutorial.org"
password = "password"
User.create!(fullname: fullname,
username: username,
email: email,
password: password,
password_confirmation: password,
activated: true,
activated_at: Time.zone.now)
end
Message.create!(email: "example#example.com",
name: "Example User",
content: "This is my message")
Organization.create!(org_name: "Fictious business",
bio: "The background of the organization here",
actioncode: 111)
99.times do |n|
org_name = Faker::Company.name
bio = Faker::Lorem.paragraph(2)
actioncode = Faker::Number.number(3)
Organization.create!(org_name: org_name,
bio: bio,
actioncode: actioncode)
end
Member.create!(organization_id: rand(1..100),
email: "me#example.com",
username: "fake-name0",
fullname: Faker::Name.name,
activated: 1,
activated_at: Time.zone.now,
password: "foobar",
password_confirmation: "foobar")
99.times do |n|
organization_id = rand(1..100)
email = "rails0-#{n+1}#example.com"
username = "fake-name#{n+1}"
fullname = Faker::Name.name
activated = rand(0..1)
activated_at = Faker::Date.backward(14) if activated==1
password = "foobar"
password_confirmation = "foobar"
Member.create!(organization_id: organization_id,
email: email,
username: username,
fullname: fullname,
activated: activated,
activated_at: activated_at,
password: password,
password_confirmation: password_confirmation)
end
To load db/seeds.rb you need to run rake db:seed.

Rspec failing when attempting to find user in DB

I can't figure out what I'm doing wrong in my model spec (user_spec.rb). I'm attempting to check that the authentication method works with a valid password, but something is going wrong in the User.find_by part of the spec I think since it returns nil. I've checked that it responds to :authenticate, :password, and :password_confirmation, which passes (I'll omit that in the code below for the sake of readability).
Here's the failure I'm getting when running the spec:
Failures:
1) User return value of authenticate method with valid password should eq #<User id: 136, fullname: "Sherwood Hickle", email: "jewell.brekke#stokes.net", created_at: "2013-11-06 23:04:35", updated_at: "2013-11-06 23:04:35", password_digest: "$2a$04$O5V2X9sZrl/u2T9W25c3Pu/PU6XaIvtZSIB39Efkid6a...">
Failure/Error: it { should eq found_user.authenticate(user.password) }
expected: #<User id: 136, fullname: "Sherwood Hickle", email: "jewell.brekke#stokes.net", created_at: "2013-11-06 23:04:35", updated_at: "2013-11-06 23:04:35", password_digest: "$2a$04$O5V2X9sZrl/u2T9W25c3Pu/PU6XaIvtZSIB39Efkid6a...">
got: #<User id: nil, fullname: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil>
(compared using ==)
Diff:
## -1,2 +1,2 ##
-#<User id: 136, fullname: "Sherwood Hickle", email: "jewell.brekke#stokes.net", created_at: "2013-11-06 23:04:35", updated_at: "2013-11-06 23:04:35", password_digest: "$2a$04$O5V2X9sZrl/u2T9W25c3Pu/PU6XaIvtZSIB39Efkid6a...">
+#<User id: nil, fullname: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil>
# ./spec/models/user_spec.rb:41:in `block (4 levels) in <top (required)>'
user_spec.rb:
require 'spec_helper'
describe User do
describe "return value of authenticate method" do
user = FactoryGirl.create(:user)
let(:found_user) { User.find_by(email: user.email) }
describe "with valid password" do
it { should eq found_user.authenticate(user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not eq user_for_invalid_password }
specify { expect(user_for_invalid_password).to be_false }
end
end
end
And I'm also using FactoryGirl to generate the username and email addresses but I don't think it has anything to do with the failure:
require 'faker'
FactoryGirl.define do
factory :user do |u|
u.fullname { Faker::Name.name }
u.email { Faker::Internet.email }
u.password { "foobar" }
u.password_confirmation { "foobar" }
end
end
The problem is the way the spec is set up. You're using an implicit subject which, for this spec, will be User.new. That's why you're seeing a User object with all nil attributes.
Your it clauses should read more like
it { found_user.authenticate(user.password).should eq user }
and
it { user_for_invalid_password.should be_nil }
which actually test the behavior.
UPDATE:
With the introduction in RSpec 3.x of expect syntax as the preferred syntax, this would now be:
it { expect(found_user.authenticate(user.password)).to eq user }
and
it { expect(user_for_invalid_password).to be_nil }

Populating database with faker

I want to populate the database with a number of stores and users, that each user corresponds to one store. The issue with the code below is that I get the error Validation failed: Email has already been taken.
namespace :db do
desc "Fill database with sample data"
task populate: :environment do
make_stores
make_users
end
end
def make_stores
50.times do
name = Faker::Company.name
manager = Faker::Name.name
address = Faker::Address.street_name
Store.create!(name: name,
manager: manager,
address: address)
end
end
def make_users
stores = Store.all(limit: 8)
99.times do |n|
first_name = Faker::Name.first_name
last_name = Faker::Name.last_name
email = "example-#{n+1}#example.org"
password = "password"
stores.each { |store| store.users.create!(first_name: first_name,
last_name: last_name,
email: email,
password: password,
password_confirmation: password) }
end
end
The problem is that you're setting the email variable before calling stores.each, so all 8 stores will get a user with the same email.
Do something like this instead:
def make_users
stores = Store.all(limit: 8)
99.times do |n|
password = "password"
stores.each do |store|
first_name = Faker::Name.first_name
last_name = Faker::Name.last_name
email = "#{store.name.parameterize}-#{n+1}#example.org"
store.users.create!(first_name: first_name,
last_name: last_name,
email: email,
password: password,
password_confirmation: password)
end
end
end
Now the first 8 users will have an email like (some-store-name)-1#example.org, next 8 will have (some-store-name)-2#example.org and so on.

Resources