diff --git a/lib/restpack_serializer/options.rb b/lib/restpack_serializer/options.rb index 83728b8..c125169 100644 --- a/lib/restpack_serializer/options.rb +++ b/lib/restpack_serializer/options.rb @@ -2,9 +2,9 @@ module RestPack::Serializer class Options attr_accessor :page, :page_size, :include, :filters, :serializer, :model_class, :scope, :context, :include_links, - :sorting + :sorting, :key - def initialize(serializer, params = {}, scope = nil, context = {}) + def initialize(serializer, params = {}, scope = nil, context = {}, key = nil) params.symbolize_keys! if params.respond_to?(:symbolize_keys!) @page = params[:page] ? params[:page].to_i : 1 diff --git a/lib/restpack_serializer/serializable/paging.rb b/lib/restpack_serializer/serializable/paging.rb index 9ad2f46..266d687 100644 --- a/lib/restpack_serializer/serializable/paging.rb +++ b/lib/restpack_serializer/serializable/paging.rb @@ -11,12 +11,15 @@ def page_with_options(options) page = page.reorder(options.sorting) if options.sorting.any? result = RestPack::Serializer::Result.new - result.resources[self.key] = serialize_page(page, options) - result.meta[self.key] = serialize_meta(page, options) + result.resources[options.key || self.key] = serialize_page(page, options) + result.meta[options.key || self.key] = serialize_meta(page, options) if options.include_links result.links = self.links - Array(RestPack::Serializer::Factory.create(*options.include)).each do |serializer| + options.include.each do |inclusion| + association = model_class.reflect_on_association inclusion + class_name = association ? association.class_name : inclusion + serializer = RestPack::Serializer::Factory.create class_name result.links.merge! serializer.class.links end end diff --git a/lib/restpack_serializer/serializable/side_load_data_builder.rb b/lib/restpack_serializer/serializable/side_load_data_builder.rb index 495cfad..9d4e9f8 100644 --- a/lib/restpack_serializer/serializable/side_load_data_builder.rb +++ b/lib/restpack_serializer/serializable/side_load_data_builder.rb @@ -17,6 +17,7 @@ def side_load_belongs_to def side_load_has_many has_association_relation do |options| + options.key = @association.name if join_table = @association.options[:through] options.scope = options.scope.joins(join_table).distinct association_fk = @association.through_reflection.foreign_key.to_sym @@ -30,7 +31,7 @@ def side_load_has_many def side_load_has_and_belongs_to_many has_association_relation do |options| join_table_name = @association.join_table - join_clause = "join #{join_table_name} on #{@association.plural_name}.id = #{join_table_name}.#{@association.class_name.foreign_key}" + join_clause = "join #{join_table_name} on #{@association.klass.table_name }.id = #{join_table_name}.#{@association.class_name.foreign_key}" options.scope = options.scope.joins(join_clause) association_fk = @association.foreign_key.to_sym options.filters = { join_table_name.to_sym => { association_fk => model_ids } } diff --git a/lib/restpack_serializer/serializable/side_loading.rb b/lib/restpack_serializer/serializable/side_loading.rb index e5a1b12..dd36b6d 100644 --- a/lib/restpack_serializer/serializable/side_loading.rb +++ b/lib/restpack_serializer/serializable/side_loading.rb @@ -28,16 +28,15 @@ def links associations.each do |association| if association.macro == :belongs_to link_key = "#{self.key}.#{association.name}" - href = "/#{association.plural_name}/{#{link_key}}" + href = "/#{association.class_name.underscore.pluralize}/{#{link_key}}" elsif association.macro.to_s.match(/has_/) - singular_key = self.key.to_s.singularize link_key = "#{self.key}.#{association.plural_name}" - href = "/#{association.plural_name}?#{singular_key}_id={#{key}.id}" + href = "/#{association.class_name.underscore.pluralize}?#{association.foreign_key}={#{key}.id}" end links.merge!(link_key => { :href => href_prefix + href, - :type => association.plural_name.to_sym + :type => association.class_name.underscore.pluralize.to_sym } ) end diff --git a/spec/fixtures/db.rb b/spec/fixtures/db.rb index be89b82..2382e57 100644 --- a/spec/fixtures/db.rb +++ b/spec/fixtures/db.rb @@ -69,6 +69,7 @@ class Artist < ActiveRecord::Base attr_accessible :name, :website has_many :albums + has_many :records, class_name: 'Album' has_many :songs has_many :payments has_many :fans, :through => :payments @@ -95,6 +96,7 @@ class Song < ActiveRecord::Base attr_accessible :title, :artist, :album belongs_to :artist + belongs_to :record, class_name: 'Album', foreign_key: 'album_id' belongs_to :album end diff --git a/spec/fixtures/serializers.rb b/spec/fixtures/serializers.rb index ff7e88a..72214ee 100644 --- a/spec/fixtures/serializers.rb +++ b/spec/fixtures/serializers.rb @@ -2,7 +2,7 @@ module MyApp class SongSerializer include RestPack::Serializer attributes :id, :title, :album_id - can_include :albums, :artists + can_include :albums, :records, :artists can_filter_by :title can_sort_by :id, :title @@ -27,7 +27,7 @@ class AlbumReviewSerializer class ArtistSerializer include RestPack::Serializer attributes :id, :name, :website - can_include :albums, :songs, :fans, :stalkers + can_include :albums, :records, :songs, :fans, :stalkers end class FanSerializer diff --git a/spec/serializable/paging_spec.rb b/spec/serializable/paging_spec.rb index 2eba6a2..8a3b38c 100644 --- a/spec/serializable/paging_spec.rb +++ b/spec/serializable/paging_spec.rb @@ -32,6 +32,7 @@ it "includes links" do page[:links].should == { 'songs.album' => { :href => "/albums/{songs.album}", :type => :albums }, + 'songs.record' => { :href => "/albums/{songs.record}", :type => :albums }, 'songs.artist' => { :href => "/artists/{songs.artist}", :type => :artists } } end @@ -99,6 +100,7 @@ album_id: first.album_id, links: { album: first.album_id.to_s, + record: first.album_id.to_s, artist: first.artist_id.to_s } } diff --git a/spec/serializable/serializer_spec.rb b/spec/serializable/serializer_spec.rb index aaa3e3a..754d49f 100644 --- a/spec/serializable/serializer_spec.rb +++ b/spec/serializable/serializer_spec.rb @@ -147,6 +147,7 @@ def custom_attributes json = serializer.as_json(@album1.songs.first) json[:links].should == { artist: @album1.artist_id.to_s, + record: @album1.id.to_s, album: @album1.id.to_s } end diff --git a/spec/serializable/side_loading/belongs_to_spec.rb b/spec/serializable/side_loading/belongs_to_spec.rb index 95b1266..d69878d 100644 --- a/spec/serializable/side_loading/belongs_to_spec.rb +++ b/spec/serializable/side_loading/belongs_to_spec.rb @@ -67,6 +67,18 @@ end end + context 'with a renamed association' do + let(:models) { [MyApp::Song.first] } + let(:options) { RestPack::Serializer::Options.new(MyApp::SongSerializer, { "include" => "records" }) } + + it 'should side-load records' do + side_loads.should == { + records: [MyApp::AlbumSerializer.as_json(MyApp::Song.first.album)], + meta: { } + } + end + end + context 'without an associated model' do let!(:b_side) { FactoryGirl.create(:song, album: nil) } let(:models) { [b_side] } diff --git a/spec/serializable/side_loading/has_many_spec.rb b/spec/serializable/side_loading/has_many_spec.rb index 77aef99..5a54e72 100644 --- a/spec/serializable/side_loading/has_many_spec.rb +++ b/spec/serializable/side_loading/has_many_spec.rb @@ -38,6 +38,17 @@ end end end + + context 'with a model renaming an association' do + let(:models){ [@artist1] } + let(:options) { RestPack::Serializer::Options.new(MyApp::ArtistSerializer, { "include" => "records" }) } + + it 'should return side-loaded records' do + side_loads[:records].count.should == @artist1.albums.count + side_loads[:meta][:records][:page].should == 1 + side_loads[:meta][:records][:count].should == @artist1.albums.count + end + end end describe '.has_many through' do