2011-07-07 22 views
1

我想通過使用rails的單個休息調用來創建複雜的休息對象實例。 在下面的示例情況中,當我使用參數散列對Person調用new時,我在控制器中出現錯誤。在一個單獨的休息調用中創建休息複雜的資源實例

我看到的ActiveSupport :: HashWithIndifferentAccess而不是

從測試通過哈希散列包含對象的數組,一個PhoneNumber時獲得意外的類型錯誤,而控制器動作參數創建的ActiveSupport :: HashWithIndifferentAccess對象。

  1. 任何修復錯誤的建議嗎?
  2. 有沒有一種更簡單的方法來創建複雜的activerecord對象與一個單一的休息電話。

即型號:

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]) 

回答

1
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 

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

0

Dinatih,感謝您的有用的答案!它幫助解決了這個問題。

我遇到了一個小問題,因爲使用「accep_nested_attributes_for:phone_numbers」, 需要散列鍵'phone_numbers_attributes',而不是'phone_numbers'的to_xml/to_json序列化默認值。測試代碼(下面)看起來有點難看,但它傳遞並正確地創建了對象。不幸的是,將json傳遞給post方法不會創建該對象。

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