Reputation: 758
I'm trying to POST some data to my Rails 4 API.
The resource:
App.factory 'House', ['$resource', ($resource) ->
$resource '/api/v1/houses/:id', { id: '@id' }
]
The JSON representation of the resource:
newHouse = {
"owner_id": "30",
"name": "test",
"address_attributes": {
"street": "somewhere",
"city": "on",
"region": "earth"
}
}
On House.save(null, $scope.newHouse)
, the server logs give me this:
Processing by Api::V1::HouseController#create as JSON
Parameters: {"owner_id"=>"34", "name"=>"test", "address_attributes"=>{"street"=>"somewhere", "city"=>"on", "region"=>"earth"}, "house"=>{"name"=>"test", "owner_id"=>"34"}}
Which is underisable, to say the least.
owner_id
and name
appear directly bellow root, and below "house" - I would expect only below "house"address_attributes
appears only directly bellow root - I would expect it to be below house
Basically I want this:
Processing by Api::V1::HouseController#create as JSON
Parameters: {"house"=>{"name"=>"test", "owner_id"=>"34", "address_attributes"=>{"street"=>"somewhere", "city"=>"on", "region"=>"earth"}}}
Any help?
EDIT
Rails controller action:
def create
house = House.new house_params
if house.save
head 200
else
render json: {
"error" => "validation errors",
"detail" => house.errors.messages
}, status: 422
end
end
def house_params
fields = [:name, :owner_id, address_attributes: [:street, :city, :region, :country, :postal_code ]]
params.require(:house).permit(fields)
end
The model House
has:
has_one :address
accepts_nested_attributes_for :address
I don't want to change the way the server handles the data. Many backends expect parameters to be held in the format I want, and even jQuery does it in its AJAX calls. AngularJS should be the one to change, or at least allow ways to configure.
Upvotes: 4
Views: 908
Reputation: 690
I am not sure you are using your $resource correctly.
EDIT: I am not sure why your class method behaves like this, the requests made should be equal./EDIT
One example of an alternative way to do it would be this:
Lets say your newHouse
model is this:
{
"owner_id": "30",
"name": "test",
"address_attributes": {
"street": "somewhere",
"city": "on",
"region": "earth"
}
}
In your html you would write something like:
<span class="btn btn-danger" ng-click="createNewHouse(newHouse)">Create new house</span>
Your Controller would bind createNewHouse() method to $scope:
$scope.createNewHouse= function(newHouse){
var newHouseInstance = new House();
newHouseInstance.house = newHouse;
newHouseInstance.$save();
}
Above code gave me a POST request with this payload (direct copy from Chrome developer console):
Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/api/v1/houses
Request Method:POST
Request Payload:
{"house":{"owner_id":"30", "name":"test", "address_attributes":{"street":"somewhere", "city":"on", "region":"earth"}}}
This will nicely translate to what you need back at the server.
Good luck!
Upvotes: 1