Làm cách nào để chuyển JSON vào ứng dụng RAILS để nó tạo các đối tượng con lồng nhau trong mối quan hệ has_many?Tạo đối tượng lồng nhau bằng JSON trong Rails
Đây là những gì tôi có cho đến thời điểm này:
Hai đối tượng mô hình.
class Commute < ActiveRecord::Base
has_many :locations
accepts_nested_attributes_for :locations, :allow_destroy => true
end
class Location < ActiveRecord::Base
belongs_to :commute
end
Với đường đi làm, tôi có bộ điều khiển chuẩn được thiết lập. Tôi muốn có thể tạo một đối tượng Commute cũng như một vài đối tượng Location con trong một cuộc gọi REST bằng cách sử dụng JSON. Tôi đã cố gắng điều như thế này:
curl -H "Content-Type:application/json" -H "Accept:application/json"
-d "{\"commute\":{\"minutes\":0,
\"startTime\":\"Wed May 06 22:14:12 EDT 2009\",
\"locations\":[{\"latitude\":\"40.4220061\",
\"longitude\":\"40.4220061\"}]}}" http://localhost:3000/commutes
Hoặc dễ đọc hơn, JSON là:
{
"commute": {
"minutes": 0,
"startTime": "Wed May 06 22:14:12 EDT 2009",
"locations": [
{
"latitude": "40.4220061",
"longitude": "40.4220061"
}
]
}
}
Khi tôi thực hiện điều đó, tôi nhận được kết quả này:
Processing CommutesController#create (for 127.0.0.1 at 2009-05-10 09:48:04) [POST]
Parameters: {"commute"=>{"minutes"=>0, "locations"=>[{"latitude"=>"40.4220061", "longitude"=>"40.4220061"}], "startTime"=>"Wed May 06 22:14:12 EDT 2009"}}
ActiveRecord::AssociationTypeMismatch (Location(#19300550) expected, got HashWithIndifferentAccess(#2654720)):
app/controllers/commutes_controller.rb:46:in `new'
app/controllers/commutes_controller.rb:46:in `create'
Có vẻ giống như các vị trí mảng JSON đang được đọc, nhưng không được hiểu là đối tượng Vị trí.
Tôi có thể dễ dàng thay đổi máy khách hoặc máy chủ, vì vậy giải pháp có thể đến từ cả hai phía.
Vì vậy, RAILS có giúp tôi dễ dàng thực hiện việc này không? Hoặc tôi có cần thêm một số hỗ trợ cho điều này vào đối tượng Đi làm của tôi không? Có lẽ thêm một phương thức from_json?
Cảm ơn bạn đã được trợ giúp.
Vì tôi đã làm việc thông qua việc này, một giải pháp hoạt động là sửa đổi bộ điều khiển của tôi. Nhưng điều này dường như không phải là cách "làm việc", vì vậy hãy cho tôi biết nếu có cách nào tốt hơn.
def create
locations = params[:commute].delete("locations");
@commute = Commute.new(params[:commute])
result = @commute.save
if locations
locations.each do |location|
@commute.locations.create(location)
end
end
respond_to do |format|
if result
flash[:notice] = 'Commute was successfully created.'
format.html { redirect_to(@commute) }
format.xml { render :xml => @commute, :status => :created, :location => @commute }
else
format.html { render :action => "new" }
format.xml { render :xml => @commute.errors, :status => :unprocessable_entity }
end
end
end
Bạn dường như có khả năng kiểm soát nguồn JSON, nhưng nếu bạn không thể, bạn sẽ xử lý "vị trí" như thế nào? – Jerome
Hãy xem, tôi vừa đăng một bản chỉnh sửa từ một câu trả lời đã bị xóa. –
Đối với bất cứ ai vẫn gặp sự cố với điều này, bạn phải tự cho phép các thuộc tính trong bộ điều khiển của bạn. Ví dụ: 'params.require (: đường đi làm) .permit (: minutes,: startTime, locations_attributes: [: vĩ độ,: kinh độ])' – Kevin