Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Filter to fix Rails API resource id usage
- Loading branch information
Showing
10 changed files
with
269 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Before filter for controllers that handle REST API requests. Conductor uses | ||
# linking to resources like <pool id='1'/> (resulting in :pool => { :id => 1 } | ||
# in request params hash) but ActiveRecord expects linking to resources like | ||
# <pool_id>1</pool_id> (resluting in :pool_id => 1 in request params hash). | ||
# | ||
# This before filter operates on request params hash to rewrite it from our | ||
# format to ActiveRecord-friendly format. | ||
# | ||
# The constructor of the filter accepts specification of what should be | ||
# transformed. E.g.: | ||
# | ||
# before_filter ResourceLinkFilter.new({ :catalog => :pool }), | ||
# :only => [:create, :update] | ||
# | ||
# would transform { :catalog => { :pool => { :id => 1 }}} | ||
# into { :catalog => { :pool_id => 1 }} | ||
# | ||
# See the specs in spec/util/resource_link_filter_spec.rb for more examples. | ||
# | ||
|
||
# NOTE This filter was taken from the aeolus conductor project: https://github.com/aeolusproject/conductor/ | ||
|
||
class Tim::ResourceLinkFilter | ||
def initialize(resource_links) | ||
@resource_links = resource_links | ||
end | ||
|
||
def before(controller) | ||
return unless controller.request.format == :xml | ||
|
||
transform_resource_links_recursively(controller.params, @resource_links) | ||
end | ||
|
||
|
||
private | ||
|
||
def transform_resource_links_recursively(subparams, sublinks) | ||
return if subparams == nil | ||
|
||
case sublinks | ||
when Symbol # then transform the link (last level of recursion) | ||
return if subparams[sublinks] == nil || subparams[sublinks][:id] == nil | ||
|
||
subparams[:"#{sublinks}_id"] = subparams[sublinks][:id] | ||
subparams.delete(sublinks) | ||
when Array # then process each item | ||
sublinks.each do |item| | ||
transform_resource_links_recursively(subparams, item) | ||
end | ||
when Hash # then descend into each entry | ||
sublinks.each_key do |key| | ||
transform_resource_links_recursively(subparams[key], sublinks[key]) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
require 'spec_helper' | ||
|
||
module Tim | ||
describe ResourceLinkFilter do | ||
|
||
describe "#transform_resource_links" do | ||
|
||
before do | ||
@controller = stub({ | ||
:request => stub({ | ||
:format => :xml | ||
}) | ||
}) | ||
@controller.stub(:params).and_return(params) | ||
end | ||
|
||
context "successful transformation" do | ||
|
||
before do | ||
ResourceLinkFilter.new(resource_links).before(@controller) | ||
end | ||
|
||
context "for a simple link" do | ||
let(:params) do { | ||
:catalog => { | ||
:id => 123 | ||
} | ||
} | ||
end | ||
let(:resource_links) { :catalog } | ||
|
||
it "transforms the link" do | ||
params[:catalog].should == nil | ||
params[:catalog_id].should == 123 | ||
end | ||
end | ||
|
||
context "for a nested link" do | ||
let(:params) do | ||
{ | ||
:catalog => { | ||
:pool => { | ||
:id => 123 | ||
} | ||
} | ||
} | ||
end | ||
let(:resource_links) { { :catalog => :pool } } | ||
|
||
it "transforms the link" do | ||
params[:catalog][:pool].should == nil | ||
params[:catalog][:pool_id].should == 123 | ||
end | ||
end | ||
|
||
context "for multiple nested links" do | ||
let(:params) do | ||
{ | ||
:catalog => { | ||
:pool => { | ||
:id => 123 | ||
}, | ||
:something => { | ||
:id => 456 | ||
} | ||
} | ||
} | ||
end | ||
let(:resource_links) { { :catalog => [:pool, :something] } } | ||
|
||
it "transforms the links" do | ||
params[:catalog][:pool].should == nil | ||
params[:catalog][:pool_id].should == 123 | ||
params[:catalog][:something].should == nil | ||
params[:catalog][:something_id].should == 456 | ||
end | ||
end | ||
|
||
context "for combined single- and double-nested links" do | ||
let(:params) do | ||
{ | ||
:catalog => { | ||
:pool => { | ||
:id => 123 | ||
}, | ||
:something => { | ||
:double_nested_1 => { | ||
:id => 456 | ||
}, | ||
:double_nested_2 => { | ||
:id => 789 | ||
} | ||
} | ||
} | ||
} | ||
end | ||
let(:resource_links) do | ||
{ | ||
:catalog => [ | ||
:pool, | ||
{ :something => [:double_nested_1, :double_nested_2] } | ||
] | ||
} | ||
end | ||
|
||
it "transforms the links" do | ||
params[:catalog][:pool].should == nil | ||
params[:catalog][:pool_id].should == 123 | ||
params[:catalog][:something][:double_nested_1].should == nil | ||
params[:catalog][:something][:double_nested_1_id].should == 456 | ||
params[:catalog][:something][:double_nested_2].should == nil | ||
params[:catalog][:something][:double_nested_2_id].should == 789 | ||
end | ||
end | ||
|
||
end | ||
|
||
context "when missing 'id' attribute in the link" do | ||
let(:params) do | ||
{ | ||
:catalog => {} | ||
} | ||
end | ||
let(:resource_links) { :catalog } | ||
|
||
it "does not transform anything" do | ||
params[:catalog].should == {} | ||
params[:catalog_id].should == nil | ||
end | ||
end | ||
|
||
context "when missing the whole link" do | ||
let(:params) { {} } | ||
let(:resource_links) { :catalog } | ||
|
||
it "does not transform anything" do | ||
params[:catalog].should == nil | ||
params[:catalog_id].should == nil | ||
end | ||
end | ||
|
||
context "when not XML request" do | ||
let(:params) { {} } | ||
|
||
before do | ||
@controller.stub_chain(:request, :format).and_return(:html) | ||
end | ||
|
||
it "does not touch params" do | ||
@controller.should_not_receive(:params) | ||
ResourceLinkFilter.new(:something).before(@controller) | ||
end | ||
end | ||
|
||
end | ||
|
||
end | ||
end |