开发者

Create rest complex resource instance in a single rest call

I would like to create complex rest object instances with a single rest call using rails. In the example case below I get an error in the controller when I call new on Person with a parameter hash.

I 开发者_JAVA百科get an error for unexpected type when seeing a ActiveSupport::HashWithIndifferentAccess and not a PhoneNumber

The hash passed from the test contains an array of Hash objects, while the controller action parameters create ActiveSupport::HashWithIndifferentAccess objects.

  1. Any suggestions to fix the error?
  2. Is there an easier way to create complex activerecord objects with a single rest call.

ie models:

class Person < ActiveRecord::Base  
  has_many :phone_numbers , :autosave => true  

class PhoneNumber  < ActiveRecord::Base  
  belongs_to :person  

person_controller_test.rb

test "should create person" do
  newperson=Person.new(:name => "test")
  newperson.phone_numbers << PhoneNumber.new(:number => "123-4567")
  person_string= newperson.to_xml(:include => :phone_numbers)
  person_hash=Hash.from_xml(course_string)
  person_hash2=person_hash['person']
  post :create, :person => person_hash2, :format => "xml"
  assert_response :success
end  

person_controller.rb

def create  
  @person = Person.new(params[:person])


class Person < ActiveRecord::Base  
  has_many :phone_numbers , :autosave => true
  # this is important for create complex nested object in one call
  accepts_nested_attributes_for :phone_numbers
end

class PhoneNumber  < ActiveRecord::Base  
  belongs_to :person
end

person_controller_test.rb

test "should create person" do
  newperson=Person.new(:name => "test")
  newperson.phone_numbers.build(:number => "123-4567") #more cleaner
  # and start from here I'm not sure but this maybe help you
  # I think that you must pass a json object 
  post :create, :person => newperson.to_json(:include => :phone_numbers), :format => "xml"
  assert_response :success
end  

link: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html


Dinatih, Thanks for the helpful answer! It helped solve the issue.

I ran into a slight problem since with "accepts_nested_attributes_for :phone_numbers", the hash key 'phone_numbers_attributes' is needed instead of the to_xml/to_json serialization default of 'phone_numbers'. The test code (below) looks a little ugly, but it passes and creates the object correctly. Also passing json to the post method unfortunately doesn't create the object.

test "should create complex person" do
  newperson=Person.new(:name => "test")
  newperson.phone_numbers.build(:number => "123-4567")
  person_string= newperson.to_xml(:include => :phone_numbers)
  person_hash=Hash.from_xml(person_string)
  person_hash2=person_hash['person']
  person_hash2[:phone_numbers_attributes] = person_hash2['phone_numbers']
  person_hash2.delete('phone_numbers')
  p person_hash2
  post :create, :person => person_hash2, :format => "xml"
  p response.body
  assert_select "person" do
    assert_select "name", {:text=>"test"}
    assert_select "phone-numbers" do
      assert_select "phone-number" do
        assert_select "number", {:text=>"123-4567"}
      end
    end
  end
  assert_response :success
end


you should also check out:

  • Gem nested_form :
    • https://github.com/ryanb/nested_form
    • examples for nested_form: https://github.com/ryanb/complex-form-examples/tree/nested_form

and

  • RailsCasts 196 / 197
    • http://railscasts.com/episodes/196-nested-model-form-part-1
    • http://railscasts.com/episodes/197-nested-model-form-part-2
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜