Orsay
Orsay

Reputation: 1130

Active Record : Validation failed on create instance

I'm trying to create a comment instance. It returns me a validation error.

A comment has one moderation and include reportable. So you can do moderation.reportable and it return comment.

I want the moderation instance to be create when a new comment is created.

class Comment < ApplicationRecord
      include Reportable

      after_create :create_moderation

      def create_moderation
        blog = self.blog
        self.create_moderation!(blog: blog)
      end
end


class Moderation < ApplicationRecord
    belongs_to :reportable, foreign_key: "reportable_id", foreign_type: "reportable_type", polymorphic: true
...
end



module Reportable
    extend ActiveSupport::Concern

    included do
      has_one :moderation, as: :reportable, foreign_key: "reportable_id", foreign_type: "reportable_type", class_name: "Moderation"
      has_many :reports, through: :moderation
end

Failure/Error: self.create_moderation!(blog: blog) ActiveRecord::RecordInvalid: Validation failed: Reportable must exist

EDIT

Trying to add :

belongs_to :reportable, foreign_key: "reportable_id", foreign_type: "reportable_type", polymorphic: true, optional: true

and get :

ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: null value in column "reportable_id" violates not-null constraint DETAIL: Failing row contains (2, 1, Comment, null, 0, null, 2017-12-01 09:02:11.81419, 2017-12-01 09:02:11.81419, Blog, unmoderate). : INSERT INTO "moderations" ("blog_id", "reportable_type", "created_at", "updated_at", "blog_type") VALUES ($1, $2, $3, $4, $5) RETURNING "id"

Upvotes: 0

Views: 454

Answers (2)

Aakanksha
Aakanksha

Reputation: 976

Try optional: true in association. Something like below:

belongs_to :reportable, foreign_key: "reportable_id", foreign_type: "reportable_type", polymorphic: true, optional: true

Refer this. The optional: true is introduced in Rails 5.

EDIT

after_create :create_moderation

def create_moderation
  blog = self.blog
  self.create_moderation!(blog: blog)
end

I see the two method names are same, i.e., after comment creation, the create_moderation is called which again calls the create_moderation. Can you try changing the name of the method maybe?

ANOTHER SUGESSTION

Can you change the method to

def create_moderation
  blog = self.blog
  Moderation.create!(blog: blog, reportable: self)
end

or

def create_moderation
  blog = self.blog
  comment = self
  comment.create_moderation!(blog: blog)
end

Do you still get the same error?

Upvotes: 1

puneet18
puneet18

Reputation: 4427

You can try below code:

class Comment < ApplicationRecord
  include Reportable

  before_create :create_moderation

  def create_moderation
    blog = self.blog
    self.build_moderation(blog: blog)
  end
end

Upvotes: 0

Related Questions