Search code examples
ruby-on-railsseeding

Rails Many To Many, seed records with extra information


I'm trying to seed the following data structure:

class Company
    has_many :user_roles 
    has_many :users, through: :user_roles
end

class User 
    has_many :user_roles 
    has_many :companies, through: :user_roles
end

class UserRole 
    belongs_to :user
    belongs_to :company
end

Besides the fields user_id and company_id, the UserRoles tables also has the field "role" that says whether the user is a "member" or a "admin to a given company.

I'm trying to seed the tables as follows:

u1 = User.create(name: 'Tester 1')
u2 = User.create(name: 'Tester 2')

e1 = Company.create(name: 'Company 1')
e2 = Company.create(name: 'Company 2')

ur1 = UserRole.create(role: 'admin', user_id: 2, company_id: 1)
ur2 = UserRole.create(role: 'member', user_id: 3, company_id: 1)
ur3 = UserRole.create(role: 'admin', user_id: 3, company_id: 2)

But when I try to verify, the UserRole table is always empty and no connection is created between the tables. If I try to add Users to the Companies directly, using

e1.users << [u1, u2]
e2.users << [u2]

Then the UserRole table shows, but I don't know how to add the 'role' information. Thanks for your help! :)


Solution

  • But when I try to verify, the UserRole table is always empty and no connection is created between the tables.

    Your UserRole objects are most likely not being created because the id's are not available. To be sure use create! instead of create so you get an exception (create will return false with no exception, that is, it fails silently) and identify the error:

    ur1 = UserRole.create!(role: 'admin', user_id: 2, company_id: 1)
    ur2 = UserRole.create!(role: 'member', user_id: 3, company_id: 1)
    ur3 = UserRole.create!(role: 'admin', user_id: 3, company_id: 2)
    

    Then the UserRole table shows, but I don't know how to add the 'role' information.

    Once you created an object, you can update an attribute in several ways (check here for more information), the most common being = followed by save:

    e1.role = "admin"
    e1.save
    

    or update:

    e1.update(role: "admin")
    

    As a side note: to ensure you got no errors related with id's, use the objects you already generated (e.g. u1, e1) to assign those id's:

    ur1 = UserRole.create!(role: 'admin', user_id: u1.id, company_id: e1.id)
    ur2 = UserRole.create!(role: 'member', user_id: u2.id, company_id: e1.id)
    ur3 = UserRole.create!(role: 'admin', user_id: u2.id, company_id: e2.id)
    

    This way no matter which id is assigned (remember that deleting records doesn't reset the auto-numeric id in database), you will always get a valid one.