Pooya
Pooya

Reputation: 1012

rails creating default child when parent doesn't have children and not showing it when parent has children

is there any trick to create default child when a parent doesn't have children and not showing it when parent has children ? an after_create callback doesn't solve the problem by itself alone.now if user creates 3 children and you call "parent.children" the result not only contains those 3 children, but also the auto-created one.

UPDATE: I need the auto-created child only when there are no other children and when there are, I don't want the auto-created one to be among the result of "parent.children"

Example:
i have a product model having many variants.a customer can order a variant and so we need a variant. but sometimes the admin don't want to add variant and thinks that a product without variant it enough.so we need a default variant to let customers to order.maybe 2 month later, the admin comes and add a variant and from this time, we don't want a default one anymore. i was looking for a nice and clean solution for this problem

Upvotes: 2

Views: 565

Answers (2)

PinnyM
PinnyM

Reputation: 35533

after_create should work just fine, assuming you associated any children before saving the parent:

class ParentModel < ActiveRecord::Base
  has_many :child_models
  after_create :ensure_child_exists

  def ensure_child_exists
    child_models.create(default: true) unless child_models.exists?
  end
end

If you then need to remove this child if new ones are added at some later point, you'll need to have a 'default' flag on the child to identify for removal, then add a callback to trigger the default child removal.

class ChildModel < ActiveRecord::Base
  attr_accessible :default
  belongs_to :parent
  after_create :remove_default_if_unneeded

  scope :default, -> { where(default: true) }

  def remove_default_if_unneeded
    parent.child_models.default.destroy_all unless self.default?
  end
end

Upvotes: 4

davidb
davidb

Reputation: 8954

Just call a method like this in the after_create callback.

def create_child_if_needed
  Child.create(:parent_id => self.id) unless self.children.any?
end

This will only create the Child object if there isnt any child in the children association.

Upvotes: 0

Related Questions