You cannot call create unless the parent is saved error when seeding in rails
Asked Answered
C

1

19

I'm trying to populate my SQLite3 database with a simple seed file that is supposed to create a bunch o movies entries in the Film table and then create some comments to this movies that are stored in Comments table.

formats = %w(Beta VHS IMAX HD SuperHD 4K DVD BlueRay)
30.times do
  film = Film.create(title: "#{Company.bs}",
                 director: "#{Name.name}",
                 description: Lorem.paragraphs.join("<br/>").html_safe,
                 year: rand(1940..2015),
                 length: rand(20..240),
                 format: formats[rand(formats.length)]
  )
  film.save
  (rand(0..10)).times do
    film.comments.create( author: "#{Name.name}",
                          title: "#{Company.bs}",
                          content: Lorem.sentences(3).join("<br/>").html_safe,
                          rating: rand(1..5)
      )
  end
end

Once i execute rake db:seed I inevitably get the error

ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved

and no records are added to either Films or Comments

My film.rb file is

class Film < ActiveRecord::Base
  has_many :comments

  validates_presence_of :title, :director
  validates_length_of :format, maximum: 5, minimum:3
  validates_numericality_of :year, :length, greater_than:  0
  validates_uniqueness_of :title
  paginates_per 4
end

The length limit on 'format' raises the error when creating a Film with formats selected from the 'format' list

Circumjacent answered 6/3, 2015 at 17:9 Comment(6)
Can you add the film.rb file. I believe due to an error the film is not getting saved. Hence when you try to create comments to that film, it doesn't get created. We need to find what error is preventing the film from being created fix it first.Wellbeing
or just change Film.create to Film.create! and you should which validation prevents film from getting saved.Cleanshaven
I agree with @Coderhs . We need to see what Film belongs_to . There is some logic in your model that is needing film's parent to be saved firstly. Once we know what Film belongs_to you will want to add seed data for the parent first, which should create the child data depending on whether or not the logic is sound.Minutes
@basia if i run Film.create!(...) i get this error message ActiveRecord::RecordInvalid: translation missing: ro.activerecord.errors.messages.record_invalCircumjacent
@Circumjacent the ending is missing, was there something after record_invalid? And are you sure Company.bs and Name.name works as expected? Also, I strongly recommend avoid using length as Film attribute name, since it's also ruby method and it might end up causing really strange situations.Cleanshaven
For me I was calling .new on the model rather than .create whoops.Ephedrine
W
40

ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved

This occurs when you try to save a child association (Comment) but the parent (Film) isn't saved yet.

It seems that film is not saved. Looking at the code, it appears that film = Film.create(...) is failing validations and thus film.comments.create(..) cannot proceed. Without knowing more about which validation is failing, that's all I can say.

I would recommend using create!(...) everywhere in seeds.rb. The bang version will raise an exception if the record isn't valid and help prevent silent failures.

Wives answered 7/3, 2015 at 16:41 Comment(1)
Thanks to you and @coderhs. My mistake was hidden from you but your advice helped me track it and learn some more. The film.format was randomly selected from this list of formats and limited in film.rb between 3 and 5. However the list of formats contained plenty of longer 'formats' 1. Using create! to see the errors is a great tip 2. Also ro.activerecord.errors.messages is an i18n error solved by properly installing that gemCircumjacent

© 2022 - 2024 — McMap. All rights reserved.