diff --git a/lib/jsonapi/serializable/relationship.rb b/lib/jsonapi/serializable/relationship.rb index a5d9395..5421b22 100644 --- a/lib/jsonapi/serializable/relationship.rb +++ b/lib/jsonapi/serializable/relationship.rb @@ -45,6 +45,18 @@ def linkage_data resources.respond_to?(:each) ? linkage_data : linkage_data.first end + + def respond_to_missing?(m, include_private = false) + @_options[:_resource].respond_to?(m) || super + end + + def method_missing(m, *args, &block) + if @_options[:_resource].respond_to?(m, true) + @_options[:_resource].send(m, *args, &block) + else + super + end + end end end end diff --git a/lib/jsonapi/serializable/resource.rb b/lib/jsonapi/serializable/resource.rb index 2670ef7..18cc500 100644 --- a/lib/jsonapi/serializable/resource.rb +++ b/lib/jsonapi/serializable/resource.rb @@ -28,6 +28,7 @@ def initialize(exposures = {}) @_relationships = self.class.relationship_blocks .each_with_object({}) do |(k, v), h| opts = self.class.relationship_options[k] || {} + opts = opts.merge(_resource: self) h[k] = Relationship.new(@_exposures, opts, &v) end @_meta = if (b = self.class.meta_block) diff --git a/spec/resource/relationship_spec.rb b/spec/resource/relationship_spec.rb index 5e42f89..26e4703 100644 --- a/spec/resource/relationship_spec.rb +++ b/spec/resource/relationship_spec.rb @@ -1,8 +1,11 @@ require 'spec_helper' describe JSONAPI::Serializable::Resource, '.relationship' do - let(:posts) { [Post.new(id: 1), Post.new(id: 2)] } - let(:user) { User.new(id: 'foo', posts: posts) } + let(:posts) do + [Post.new(id: 1, title: 'Post 1'), + Post.new(id: 2, title: 'Post 2')] + end + let(:user) { User.new(id: 'foo', name: 'Lucas', posts: posts) } it 'forwards to @object by default' do klass = Class.new(JSONAPI::Serializable::Resource) do @@ -109,4 +112,27 @@ expect(actual).to eq(expected) end + + it 'forwards missing methods to parent resource if available' do + klass = Class.new(JSONAPI::Serializable::Resource) do + type 'users' + + attribute(:name) { "#{@object.name} - writer of #{primary_post.title}" } + + has_one :primary_post do + data { primary_post } + end + + private + + def primary_post + @object.posts.first + end + end + + resource = klass.new(object: user, _class: { Post: SerializablePost }) + actual = resource.as_jsonapi(include: [:primary_post]) + expect(actual[:attributes][:name]).to eq('Lucas - writer of Post 1') + expect(actual[:relationships][:primary_post][:data][:id]).to eq('1') + end end