class RailsAdminClone::ModelCloner

Public Class Methods

new(original_model) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 4
def initialize(original_model)
  @original_model = original_model
end

Public Instance Methods

class_model() click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 12
def class_model
  original_model.class
end
default_clone() click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 16
def default_clone
  new_object = clone_object(original_model)
  clone_recursively!(original_model, new_object)

  new_object
end
method_clone(method) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 23
def method_clone(method)
  original_model.send(method)
end
original_model() click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 8
def original_model
  @original_model
end

Protected Instance Methods

assign_association(association, old_association, new_association) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 67
def assign_association(association, old_association, new_association)
  assign_attributes_for(new_association, get_association_attributes_from(old_association, association))
  new_association = clone_recursively!(old_association, new_association)
end
assign_attributes_for(object, attributes) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 59
def assign_attributes_for(object, attributes)
  if class_with_strong_parameters?(object.class)
    object.assign_attributes attributes
  else
    object.assign_attributes attributes, without_protection: true
  end
end
attributes_black_list_from_association(association) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 41
def attributes_black_list_from_association(association)
  model = association.class_name.constantize
  attributes = attributes_black_list_from_model(model)
  attributes + [association.try(:foreign_key), association.try(:type)]
end
attributes_black_list_from_model(model) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 37
def attributes_black_list_from_model(model)
  [model.primary_key, model.inheritance_column] + timestamp_columns
end
build_from(object) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 135
def build_from(object)
  object.class.new
end
build_has_one(new_object, association, old_association) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 103
def build_has_one(new_object, association, old_association)
  new_object.send(:"build_#{association.name}").tap do |new_association|
    assign_association(association, old_association, new_association)
  end
end
build_has_one?(object, association) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 99
def build_has_one?(object, association)
  object.send(association.name) && association.options[:through].blank?
end
class_with_strong_parameters?(klass) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 29
def class_with_strong_parameters?(klass)
  defined?(ActiveModel::ForbiddenAttributesProtection) && klass.include?(ActiveModel::ForbiddenAttributesProtection)
end
clone_habtm(old_object, new_object) click to toggle source

clone has_and_belongs_to_many associtations

# File lib/rails_admin_clone/model_cloner.rb, line 126
def clone_habtm(old_object, new_object)
  old_object.class.reflect_on_all_associations.select{|a| a.macro == :has_and_belongs_to_many}.each do |association|
    method_ids = "#{association.name.to_s.singularize.to_sym}_ids"
    new_object.send(:"#{method_ids}=", old_object.send(method_ids))
  end

  new_object
end
clone_has_many(old_object, new_object) click to toggle source

clone has_many associations

# File lib/rails_admin_clone/model_cloner.rb, line 110
def clone_has_many(old_object, new_object)
  associations = old_object.class.reflect_on_all_associations(:has_many)
    .select{|a| !a.options.keys.include?(:through)}

  associations.each do |association|
    old_object.send(association.name).each do |old_association|
      new_object.send(association.name).build.tap do |new_association|
        assign_association(association, old_association, new_association)
      end
    end
  end

  new_object
end
clone_has_one(old_object, new_object) click to toggle source

clone has_one associations

# File lib/rails_admin_clone/model_cloner.rb, line 90
def clone_has_one(old_object, new_object)
  old_object.class.reflect_on_all_associations(:has_one).each do |association|
    old_association = old_object.send(association.name)
    build_has_one(new_object, association, old_association) if build_has_one?(old_object, association)
  end

  new_object
end
clone_object(old_object) click to toggle source

clone object without associations

# File lib/rails_admin_clone/model_cloner.rb, line 82
def clone_object(old_object)
  object = build_from(old_object)
  assign_attributes_for(object, get_model_attributes_from(old_object))

  object
end
clone_recursively!(old_object, new_object) click to toggle source

deep clone

# File lib/rails_admin_clone/model_cloner.rb, line 73
def clone_recursively!(old_object, new_object)
  new_object = clone_has_one  old_object, new_object
  new_object = clone_habtm    old_object, new_object
  new_object = clone_has_many old_object, new_object

  new_object
end
get_association_attributes_from(object, association) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 53
def get_association_attributes_from(object, association)
  object.attributes.select do |k,v|
    !attributes_black_list_from_association(association).include?(k)
  end
end
get_model_attributes_from(object) click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 47
def get_model_attributes_from(object)
  object.attributes.select do |k,v|
    !attributes_black_list_from_model(object.class).include?(k)
  end
end
timestamp_columns() click to toggle source
# File lib/rails_admin_clone/model_cloner.rb, line 33
def timestamp_columns
  %w(created_at created_on updated_at updated_on)
end