Skip to content

Commit

Permalink
Add HasOne Association
Browse files Browse the repository at this point in the history
According to some PDC server's primary_key is multiple,
add a mapping in identity. Not sure if this a good implementation
or not.

JIRA: PDC-1685
  • Loading branch information
simozhan committed Jan 12, 2018
1 parent f06cb84 commit d67c65f
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/pdc/resource/associations.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'pdc/resource/associations/has_many'
require 'pdc/resource/associations/association'
require 'pdc/resource/associations/builder'
require 'pdc/resource/associations/has_one'

module PDC::Resource
module Associations
Expand All @@ -25,6 +26,14 @@ def has_many(name, options = {})
end
end

def has_one(name, options = {})
create_association(name, HasOne, options)

define_method "build_#{name}" do |attributes = nil|
association(name).build(attributes)
end
end

private

def create_association(name, type, options)
Expand Down
4 changes: 4 additions & 0 deletions lib/pdc/resource/associations/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ def initialize(klass, parent, name, options = {})
@name = name
end

def load
find_one! # Override for plural associations that return an association object
end

private

def foreign_key
Expand Down
29 changes: 29 additions & 0 deletions lib/pdc/resource/associations/has_one.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module PDC::Resource
module Associations
class HasOne < Association
def initialize(*args)
super
@options.reverse_merge!(uri: "#{parent.class.model_name.plural}/:#{foreign_key}/#{@name}")
collect_params
end

def collect_params
p_mapping = parent.class.mapping
s_foreign_key = foreign_key.to_s
if s_foreign_key.include? '/'
s_foreign_key.split('/').each do |fk|
p_mapping_value = p_mapping[fk.to_sym]
@params[fk] =
if p_mapping && p_mapping_value
parent.attributes[p_mapping_value.to_sym]
else
parent.attributes[fk]
end
end
else
@params[foreign_key] = parent.id
end
end
end
end
end
8 changes: 8 additions & 0 deletions lib/pdc/resource/identity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ def resource_path
@resource_path ||= model_name.collection.sub(%r{^pdc\/}, '').tr('_', '-')
end

def mapping
@mapping || {}
end

def mapping=(mapping = {})
@mapping = mapping
end

private

def default_uri
Expand Down
47 changes: 47 additions & 0 deletions spec/fixtures/vcr/has_one_assocation.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions spec/pdc/resource/associations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,23 @@
ProductVersion.new.non_existings
end
end
end

describe 'has many' do
it 'has many association' do
releases = ProductVersion.new(product_version_id: 'dp-1').releases.to_a
assert_equal 'dp-1.0', releases.first.release_id
end
end

describe 'find has many' do
it 'find on has many association' do
release = ProductVersion.new(product_version_id: 'dp-1').releases.find('dp-1.0')
assert_equal 'dp-1.0', release.release_id
end
end

describe 'scope' do
it 'scopes on associations' do
releases = ProductVersion.new(product_version_id: 'dp-1').releases.where(release_id: 'dp-1.0').to_a
assert_equal 'dp-1.0', releases.first.release_id
Expand Down Expand Up @@ -98,4 +104,11 @@
assert_requested endpoint2, times: 1
end
end

describe 'has_one' do
it 'has_one assocation' do
variant_cpe = ReleaseVariant.new(release: 'dp-1.0', uid: 'Client').variant_cpe
assert_equal 'cpe:/asdff', variant_cpe.cpe
end
end
end
9 changes: 9 additions & 0 deletions spec/support/fixtures.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,13 @@ class ProductVersion < Association
class Release < Association
self.primary_key = :release_id
end

class ReleaseVariant < Association
has_one :variant_cpe, uri: 'rest_api/v1/variant-cpes/?release=:release&variant_uid=:uid', foreign_key: 'release/variant_uid'
self.mapping = { variant_uid: 'uid' }
end

class VariantCpe < Association
self.primary_key = :id
end
end

0 comments on commit d67c65f

Please sign in to comment.