get parent id on a nested attribute in rake seed - ruby-on-rails

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!

Related

ActiveRecord::AssociationTypeMismatch: User(#35560) expected, got ... which is an instance of User(#22700)

I've been getting intermittent errors while seeding with rails. I'm hoping someone can help provide some insight into the different types of the User class.
The error in full:
ActiveRecord::AssociationTypeMismatch: User(#35560) expected, got #<User id: "bedc7c4e-cdd2-4ea1-a7ee-4e6642467fba", email: "phil#email.domain", jti: "7376cf41-7f88-407d-8365-1e311d946b88", ios_device_token: nil, fcm_device_token: nil, first_name: "Phil", last_name: "6", phone_number: nil, date_of_birth: nil, super_user: true, created_at: "2023-02-08 08:16:37.559974000 +0000", updated_at: "2023-02-08 08:16:37.559974000 +0000"> which is an instance of User(#22700)
The code which causes it:
user = User.new(
first_name: 'Phil',
last_name: '6',
email: 'phil#email.domain',
super_user: true,
password: 'test1234'
)
user.skip_confirmation!
user.save!
organisation = Organisation.find_by_name('Team')
Membership.create!(
user:,
organisation:,
verified: true,
verified_at: now,
organisation_admin: true,
shift_admin: true,
email: 'phil.6#group.com',
email_confirmed: true,
category: organisation.categories.find_by_name('Developer')
)
organisation = Organisation.find_by_name('Test Org')
membership = Membership.create!(
user:,
organisation:,
verified: true,
verified_at: now,
email: 'phil#testorg.com',
email_confirmed: true
)
If I pause execution before the error I can see that user == User.first is false despite User.first and user being these two lines, which are visually identical:
#<User id: "6ce62b08-cf4c-4bfa-878a-02a1ed889c69", email: "phil#email.domain", jti: "710948b6-5f4f-40ea-ab9f-df8e3b1219c3", ios_device_token: nil, fcm_device_token: nil, first_name: "Phil", last_name: "6", phone_number: nil, date_of_birth: nil, super_user: true, created_at: "2023-02-08 08:17:06.024800000 +0000", updated_at: "2023-02-08 08:17:06.024800000 +0000">
#<User id: "6ce62b08-cf4c-4bfa-878a-02a1ed889c69", email: "phil#email.domain", jti: "710948b6-5f4f-40ea-ab9f-df8e3b1219c3", ios_device_token: nil, fcm_device_token: nil, first_name: "Phil", last_name: "6", phone_number: nil, date_of_birth: nil, super_user: true, created_at: "2023-02-08 08:17:06.024800000 +0000", updated_at: "2023-02-08 08:17:06.024800000 +0000">
It's the same thing if I compare user.class and User.first.class, they look the same but a comparison evaluates to false.
Am I doing something to mutate the local variable?
What you should be doing here is to create an assocation:
class User < ApplicationRecord
has_many :memberships
end
Then you create the memberships through that assocation instead:
user = User.create!(
first_name: 'Phil',
last_name: '6',
email: 'phil#email.domain',
super_user: true,
password: 'test1234',
confirmed_at: Time.current # the easy way to skip Devise::Confirmable
)
# make sure you use the bang method so that you're not just getting a nil
organisation = Organisation.find_by_name!('Test Org')
user.memberships.create!(
organisation: organisation,
verified: true,
verified_at: now,
organisation_admin: true,
shift_admin: true,
email: 'phil.6#group.com',
email_confirmed: true,
category: organisation.categories.find_by_name!('Developer')
)

Link models to users in seed data

I'm creating seed data and I can't figure out how to link the user's email to the auction model in the seller attribute on the seeds page, and I can't figure out how to link the user to the review seed data.
seeds.rb
u1 = User.create!(
name: 'Alice Johnson',
email: 'alice#email.com',
password: 'password',
rating: '3',
location: 'Memphis, TN'
)
u2 = User.create!(
name: 'Bob Jones',
email: 'bob#email.com',
password: 'password',
rating: '4',
location: 'Nashville, TN'
)
a2 = Auction.create!(
seller: , #Help
auction_start_time: DateTime.strptime("4/23/2020 08:00", "%m/%d/%Y %R"),
auction_end_time: DateTime.strptime("5/1/2020 11:59", "%m/%d/%Y %R"),
category: "Home",
current_price: 70.0,
highest_bid: 100.0,
highest_bidder: "John Doe",
name: "Vacuum",
active: TRUE
)
r1 = Review.create!(
user:u2,
description: 'The best',
rating:5,
reviewer: 'bob#email.com',
title:'Great',
user_reviewed:'Alice Johnson'
)
db/migration/addUSerFkColToReviews
class AddUserFkColToReviews < ActiveRecord::Migration[6.0]
def change
add_reference :reviews, :user, foreign_key: true
end
end
to be able to use seller: user you have to have this association in your Auction model like this:
belongs_to :seller, calss_name: 'User'
Also note you have to make sure that the seller_id column is present in your auctions table.

How to repeat single hash multiple times in one array?

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

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!

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.

Resources