Skip to content

Commit

Permalink
Add GenericObject#property_associations to return the objects associa…
Browse files Browse the repository at this point in the history
…tions.
  • Loading branch information
lfu committed Sep 8, 2017
1 parent f944cd4 commit 2009663
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 6 deletions.
23 changes: 17 additions & 6 deletions app/models/generic_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class GenericObject < ApplicationRecord
delegate :property_attribute_defined?,
:property_defined?,
:type_cast,
:property_associations, :property_association_defined?,
:property_association_defined?,
:property_methods, :property_method_defined?,
:to => :generic_object_definition, :allow_nil => true

Expand All @@ -35,6 +35,12 @@ def property_attributes
end
end

def property_associations
properties.select { |k, _| property_association_defined?(k) }.each_with_object({}) do |(k, _), h|
h[k] = _property_getter(k)
end
end

def delete_property(name)
if !property_attribute_defined?(name) && !property_association_defined?(name)
valid_property_names = generic_object_definition.property_attributes.keys + generic_object_definition.property_associations.keys
Expand All @@ -52,7 +58,7 @@ def add_to_property_association(name, objs)
name = name.to_s
properties[name] ||= []

klass = property_associations[name].constantize
klass = generic_object_definition.property_associations[name].constantize
selected = objs.select { |obj| obj.kind_of?(klass) }
properties[name] = (properties[name] + selected.pluck(:id)).uniq if selected
save!
Expand All @@ -63,10 +69,14 @@ def delete_from_property_association(name, objs)
name = name.to_s
properties[name] ||= []

klass = property_associations[name].constantize
klass = generic_object_definition.property_associations[name].constantize
selected = objs.select { |obj| obj.kind_of?(klass) }
properties[name] = properties[name] - selected.pluck(:id)
common_ids = properties[name] & selected.pluck(:id)
properties[name] = properties[name] - common_ids
return unless properties_changed?

save!
klass.where(:id => common_ids).to_a
end

def inspect
Expand All @@ -75,7 +85,7 @@ def inspect
end

attributes_as_string += ["attributes: #{property_attributes}"]
attributes_as_string += ["associations: #{property_associations.keys}"]
attributes_as_string += ["associations: #{generic_object_definition.property_associations.keys}"]
attributes_as_string += ["methods: #{property_methods}"]

prefix = Kernel.instance_method(:inspect).bind(self).call.split(' ', 2).first
Expand Down Expand Up @@ -126,13 +136,14 @@ def _property_getter(name)

def _property_setter(name, value)
name = name.to_s

val =
if property_attribute_defined?(name)
# property attribute is of single value, for now
type_cast(name, value)
elsif property_association_defined?(name)
# property association is of multiple values
value.select { |v| v.kind_of?(property_associations[name].constantize) }.uniq.map(&:id)
value.select { |v| v.kind_of?(generic_object_definition.property_associations[name].constantize) }.uniq.map(&:id)
end

self.properties = properties.merge(name => val)
Expand Down
68 changes: 68 additions & 0 deletions spec/models/generic_object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@
go_assoc.save!
expect(go_assoc.vms.count).to eq(1)
end

it 'method returns all associations' do
host = FactoryGirl.create(:host)
go_assoc.hosts = [host]

result = go_assoc.property_associations
expect(result["vms"]).to match_array([vm1, vm2])
expect(result["hosts"]).to match_array([host])
end
end

describe 'property methods' do
Expand Down Expand Up @@ -244,4 +253,63 @@
expect { go.delete_property("some_attribute_not_defined") }.to raise_error(RuntimeError)
end
end

describe '#add_to_property_association' do
let(:new_vm) { FactoryGirl.create(:vm_vmware) }
subject { go.add_to_property_association("vms", vm1) }

it 'adds objects into association' do
subject
expect(go.vms.count).to eq(1)

go.add_to_property_association(:vms, [new_vm])
expect(go.vms.count).to eq(2)
end

it 'does not add duplicate object' do
subject
expect(go.vms.count).to eq(1)

subject
expect(go.vms.count).to eq(1)
end

it 'does not add object from differnt class' do
go.add_to_property_association("vms", FactoryGirl.create(:host))
expect(go.vms.count).to eq(0)
end

it 'does not accept object id' do
go.add_to_property_association(:vms, new_vm.id)
expect(go.vms.count).to eq(0)
end
end

describe '#delete_from_property_association' do
before { go.add_to_property_association("vms", [vm1]) }
let(:new_vm) { FactoryGirl.create(:vm_vmware) }

it 'deletes objects from association' do
result = go.delete_from_property_association(:vms, [vm1])
expect(go.vms.count).to eq(0)
expect(result).to match_array([vm1])
end

it 'does not delete object that is not in association' do
expect(go.vms.count).to eq(1)
result = go.delete_from_property_association(:vms, [new_vm])
expect(go.vms).to match_array([vm1])
expect(result).to be_nil
end

it 'does not delete object from differnt class' do
result = go.delete_from_property_association(:vms, [FactoryGirl.create(:host)])
expect(go.vms).to match_array([vm1])
expect(result).to be_nil
end

it 'does not accept object id' do
expect(go.delete_from_property_association(:vms, vm1.id)).to be_nil
end
end
end

0 comments on commit 2009663

Please sign in to comment.