Search code examples
ruby-on-railsherokuself-reference

Heroku won't seed when first user is self-referencing itself in Rails


I'm trying to self-reference a user and so in my user.rb:

# return all users created under this user (admin/manager)
has_many :customers, class_name: "User", foreign_key: :creator_id
# return this customer's creator
belongs_to :creator, class_name: "User"

and in my schema.rb, in users table I have:

t.integer  "creator_id"

I have a seed file in Rails where the first declared user references itself (via creator_id). I tried the following which successfully seeds when I rails db:seed and I can run the app in localhost

u1 = User.new(first_name: "John", last_name: "Doe", email: "johndoe@example.com", password: "password", password_confirmation: "password", role_id: r1.id)
u1.creator_id = 1
u1.save

However, when I seed in Heroku, it always throws me an error:

ActiveRecord::RecordInvalid: Validation failed: Creator must exist

which stops seeding the rest of the users. I'm wondering why my localhost is ok with it but Heroku won't let it. What am I doing wrong?

Any help is appreciated. Thank you :-)


Solution

  • Your development environment's database might rely on ids that start at 1... but you can't assume that all databases will do that.

    I suggest you actually pull out the creator's User model from your database and use the actual id that it has.

    "There are no user in the prod database yet. It is the very first user I'm trying to seed. I can't create it so that the db will assign a user id because it needs a creator_id which relies on its own user id."

    Ah... then you have a problem... because you've declared that creator_id must be present, your code will look for a User with the id you've given to creator_id and fail to find it... and thus you can't ever add the first User.

    Depending on whether this constraint has been set up just in Rails (ie validates :creator, presence: true) or in the database a proper databaseNOT NULLCONSTRAINT`), will depend on the solution to use.

    If it's just in Rails, then you can simply save the User without running the validation callbacks and then add the valid creator_id eg:

    u1 = User.new(first_name: "John", last_name: "Doe", email: "johndoe@example.com", password: "password", password_confirmation: "password", role_id: r1.id)
    u1.save(false)
    u1.update(creator_id: u1.id)
    

    If there is a NOT NULL constraint in the db... then you will need to do all this via SQL only, but first turn off the CONSTRAINT...