New error in ActiveRecord when activating user from rails c

AI-generated summary

A user encountered an error when trying to activate a newly created user in Rails console, receiving the message ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved. The issue was traced to the user not being saved due to validation failure—specifically, the password was too short. merefield clarified that using create! or save! would reveal the validation errors, which confirmed the password was invalid. Once the password was corrected, the user could be saved and activated successfully. markschmucker confirmed the issue was resolved.

Previously (up to a few months ago), I have been able to create users with:

sudo -s
cd /var/discourse
./launcher enter app
rails c
u = User.create(username: "dunderhead", email: "dunderhead@live.com", password: "password")
u.activate

Now the activate step fails with:

[7] pry(main)> u.activate
ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved
from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.8/lib/active_record
/associations/collection_association.rb:342:in `_create_record

What do I need to do?

Does the user get a user ID when you create it? I suspect not, but I don’t know why.

No.

[4] pry(main)> u = User.create(username: "dunderhead", email: "dunderhead@live.com", password: "password")
=> #<User:0x00007fb0c48b17e0
 id: nil,
 username: "dunderhead",
 created_at: nil,
 updated_at: nil,
 name: nil,
 seen_notification_id: 0,
 last_posted_at: nil,
 password_hash: nil,
 salt: nil,
 active: false,
 username_lower: nil,
 last_seen_at: nil,
 admin: false,
 last_emailed_at: nil,
 trust_level: 0,
 approved: false,
 approved_by_id: nil,
 approved_at: nil,
 previous_visit_at: nil,
 suspended_at: nil,
 suspended_till: nil,
 date_of_birth: nil,
 views: 0,
 flag_level: 0,
 ip_address: nil,
 moderator: false,
 title: nil,
 uploaded_avatar_id: nil,
 locale: nil,
 primary_group_id: nil,
 registration_ip_address: nil,
 staged: false,
 first_seen_at: nil,
 silenced_till: nil,
 group_locked_trust_level: nil,
 manual_locked_trust_level: nil,
 secure_identifier: nil,
 last_digest_at: nil,
 flair_group_id: nil,
 last_seen_reviewable_id: nil,
 password_algorithm: nil>

I did try saving the user before activating, as the error suggested, but to no avail. I don’t know what the error message means by “parent”.

[5] pry(main)> u.save
=> false
[6] pry(main)> u.activate
ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved
from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.8/lib/active_record/
associations/collection_association.rb:342:in `_create_record'

You are failing validation here, that’s why.

e.g. the password is too short.

You can bubble up the exception doing this:

u.save!

which gives, e.g.:

ActiveRecord::RecordInvalid: Validation failed: Password is too short (minimum is 10 characters)
from /home/robert/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.0.8.1/lib/active_record/validations.rb:80:in `raise_validation_error'

A quicker way of getting to that would have been to add an exclamation mark after the create:

 u = User.create!(username: "dunderhead", email: "dunderhead@live.com", password: "password")

An ID will not be assigned until you give the object fully valid attributes, either on create or on save after fixing them.

Only when you have an instantiated object can you proceed to run methods on it.

Thanks guys, the password was too short. All good now.