Joey M. Ferguson
Joey M. Ferguson

Reputation: 25

Getting error on ruby model: "You cannot call create unless the parent is saved"

So I created a method in one of my models for parsing hashtags in a body of text. Here is the model:

class Conversation < ActiveRecord::Base
  has_many :comments
  has_many :hashtags, as: :hashtaggable, autosave: true
  belongs_to :user
  attr_accessible :description, :title, :user_id
  before_save :create_hashtags

  private

  def create_hashtags
    if self.description_changed? || self.hashtags.empty?
      ##scan for new hashtags
      scanned_tags = self.description.scan(/#\w+/)
      ##delete old hashtag
      self.hashtags.destroy_all unless self.hashtags.empty?
      ##save the new hashtag
      scanned_tags.each do |hashtag|
        self.hashtags.create name: hashtag
      end unless scanned_tags.empty?
    end
  end

  validates :description, presence: true, length: { in: 5..400 }
  validates :title, presence: true, length: {in: 20..250}
  validates :user, presence: true
end

This works fine if I'm updating an already existing "conversation," but if I try to create a new one, I get this error:

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

Is there something I'm missing in my model? I've tried everything.

Upvotes: 0

Views: 7778

Answers (1)

zeantsoi
zeantsoi

Reputation: 26193

Change the following line:

before_save :create_hashtags

to this:

after_save :create_hashtags

Explanation: The ActiveRecord callback you're trying to make to create_hashtags involves saving a child association on a parent. There are a number of ways to save a child on a parent, but in your case, it's easiest to simply ensure that the parent record is saved before the child(ren) association is made.

before_save callbacks are executed before the saving of the object, and as such, no child associations can be saved (since the parent object isn't saved yet). In contrast, after_save executes the callback after the object is saved – and thus it's possible to associate children with the object.

Upvotes: 11

Related Questions