18

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

Cristi
  • 445
  • 2
  • 4
  • 14
  • 1
    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. – coderhs Mar 06 '15 at 17:16
  • 3
    or just change `Film.create` to `Film.create!` and you should which validation prevents film from getting saved. – basiam Mar 06 '15 at 17:18
  • 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. – James Mar 06 '15 at 17:43
  • @basia if i run Film.create!(...) i get this error message `ActiveRecord::RecordInvalid: translation missing: ro.activerecord.errors.messages.record_inval` – Cristi Mar 07 '15 at 01:48
  • @Cristi 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. – basiam Mar 07 '15 at 16:08
  • For me I was calling `.new` on the model rather than `.create` whoops. – CTS_AE Feb 04 '20 at 02:40

1 Answers1

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.

messanjah
  • 8,977
  • 4
  • 27
  • 40
  • 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 gem – Cristi Mar 07 '15 at 19:13