Android デバイスから XML 構造を Rails アプリケーションに送信しています。この XML の構造は次のようになります。
<Updates>
<Update type="1"><Data>...</Data><Something>...</Something></Update>
<Update type="2"><Data>...</Data><Something>...</Something></Update>
<Update type="3"><Data>...</Data><Something>...</Something></Update>
</Updates>
Rails がこれをハッシュに変換しているように見えます。
各タグ (この番号はさまざまです) を調べて、その type 属性を取得し、他の要素内のデータを使用するにはどうすればよいですか?
私はこれに苦労してきました。
これが私が取得し続けるエラーです(TypeError(文字列を整数に変換できません)):
Started POST "/update/index?auth_token=rAyrJgr4w6LNBSXRoYie" for 127.0.0.1 at 2012-04-11 23:44:29 -0500
Processing by UpdateController#index as XML
Parameters: {"Updates"=>{"Update"=>{"type"=>"2", "levelID"=>"7", "S1"=>"1", "S2"=>"0", "S3"=>"0"}}, "auth_token"=>"rAyrJgr4w6LNBSXRoYie"}
WARNING: Can't verify CSRF token authenticity
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."authentication_token" = 'rAyrJgr4w6LNBSXRoYie' LIMIT 1
(0.1ms) begin transaction
(0.5ms) UPDATE "users" SET "current_sign_in_at" = '2012-04-12 04:44:29.385406', "sign_in_count" = 2, "updated_at" = '2012-04-12 04:44:29.386311' WHERE "users"."id" = 1
(2.2ms) commit transaction
Completed 500 Internal Server Error in 9ms
TypeError (can't convert String into Integer):
app/controllers/update_controller.rb:21:in `fetch'
app/controllers/update_controller.rb:21:in `block in index'
app/controllers/update_controller.rb:19:in `each'
app/controllers/update_controller.rb:19:in `index'
Rendered /Users/colegroff/.rvm/gems/ruby-1.9.2-p290@exterminator/gems/actionpack-3.2.1/lib/action_dispatch/middleware/templates/rescues/_trace.erb (50.2ms)
Rendered /Users/colegroff/.rvm/gems/ruby-1.9.2-p290@exterminator/gems/actionpack-3.2.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.8ms)
Rendered /Users/colegroff/.rvm/gems/ruby-1.9.2-p290@exterminator/gems/actionpack-3.2.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (55.6ms)
----------------------------------------------------
params[:Updates].class: ActiveSupport::HashWithIndifferentAccess
----------------------------------------------------
update.inspect: ["type", "2"]
これが私のコントローラーです:
class UpdateController < ApplicationController
before_filter :authenticate_user!
def index
output = ""
puts "----------------------------------------------------"
puts "params[:Updates].class: #{params[:Updates].class.to_s}"
puts "----------------------------------------------------"
if !params[:Updates].nil?
params[:Updates][:Update].each do |update|
puts "update.inspect: #{update.inspect}"
puts "update.fetch(\"type\"): #{update.fetch("type")}"
puts "update.fetch(\"type\").class.to_s: #{update.fetch("type").class.to_s}"
update_type = update.fetch("type")
puts "update_type: #{update_type}"
case update_type
when "0"
puts "inside case 0"
number_of_bug_bucks = update.fetch("numberOfBugBucks")
update_bug_bucks(number_of_bug_bucks)
output += "<Update type='0'>"
output += "<numberOfBugBucks>#{current_user.bug_bucks.to_s}</numberOfBugBucks>"
output += "</Update>"
when "2"
puts "inside case 2"
level_id = update.fetch("levelID")
star_1 = update.fetch("S1")
star_2 = update.fetch("S2")
star_3 = update.fetch("S3")
updated_level = update_level_data(level_id, star_1, star_2, star_3)
output += "<Update type='2'>"
output += "<levelID>#{updated_level[0].level_id}</levelID>"
output += "<S1>#{updated_level[0].star_1}</S1>"
output += "<S2>#{updated_level[0].star_2}</S2>"
output += "<S3>#{updated_level[0].star_3}</S3>"
output += "</Update>"
when "3"
puts "inside case 3"
tower_id = update.fetch("towerID")
tower_state = update.fetch("towerState")
updated_tower = update_tower_data(tower_id, tower_state)
output += "<Update type='3'>"
output += "<towerID>#{updated_tower[0].tower_id}</towerID>"
output += "<towerState>#{updated_tower[0].tower_state}</towerState>"
output += "</Update>"
when "4"
puts "inside case 4"
authentication_token = update.fetch("AuthToken")
update_is_logged_in = update_is_logged_in(authentication_token)
output += "<Update type='4'>"
output += "<AuthToken>#{update_is_logged_in[0].authentication_token}</AuthToken>"
output += "</Update>"
end
puts "----------------------------------------------------"
end
end
puts "output: #{output}"
puts "----------------------------------------------------"
respond_to do |format|
format.xml { render :xml => "<Updates>" + output + "</Updates>" }
end
end
private # private methods below:
def update_bug_bucks(number_of_bug_bucks)
current_user.update_attribute("bug_bucks", number_of_bug_bucks)
end
def update_level_data(level_id, star_1, star_2, star_3)
updated_level = Level.where("level_id = ? AND user_id = ?", level_id, current_user.id)
if updated_level.empty?
current_user.levels.create(attributes = {:level_id => level_id, :star_1 => star_1, :star_2 => star_2, :star_3 => star_3})
else
updated_level[0].update_attributes(:star_1 => star_1, :star_2 => star_2, :star_3 => star_2)
end
updated_level
end
def update_tower_data(tower_id, tower_state)
updated_tower = Tower.where("tower_id = ? AND user_id = ?", tower_id, current_user.id)
if updated_tower.empty?
current_user.towers.create(attributes = {:tower_id => tower_id, :tower_state => tower_state})
else
updated_tower[0].update_attributes(:tower_state => tower_state)
end
updated_tower
end
def update_is_logged_in(authentication_token)
logged_out_user = User.where("authentication_token = ?", authentication_token).first
logged_out_user.reset_authentication_token!
logged_out_user.update_attribute("is_logged_in", false)
end
############################################################################################################################
############################################################################################################################
end