I am trying to pass an array of user objects from flash to rails 3 and update them all at once. Here is the code that I am using.
def update_by_fbid
if params[:users]
params[:users].each do |u|
puts u
user = User.find_by_fbid(u.fbid)
user.update_attributes(:first_name => u.first_name, :last_name => u.last_name)
end
end
render :json => {:updated_users => true}
end
Here is my code from Flash
private function updateUsers(e:Event):void
{
var users:Array = [{fbid:"93847566", first_name:"Joe", last_name:"Blow"},
{fbid:"7654321", first_name:"Ronda", last_name:"Smith"}
];
var vars : URLVariables = new URLVariables();
vars.users = users;
var request : URLRequest = new URLRequest("http://localhost:3000/update");
request.method = URLRequestMethod.POST;
request.data = vars;
var loade开发者_JS百科r : URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, registerHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
loader.load(request);
}
here is the error that I am seeing in the terminal
Started POST "/update" for 127.0.0.1 at Sat Jan 22 13:41:42 -0600 2011
Processing by UsersController#update_by_fbid as HTML
Parameters: {"users"=>"[object Object]"}
Completed in 8ms
NoMethodError (undefined method `fbid' for "[object Object]":String):
app/controllers/users_controller.rb:68:in `update_by_fbid'
app/controllers/users_controller.rb:66:in `each'
app/controllers/users_controller.rb:66:in `update_by_fbid'
Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (3.8ms)
Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (8.9ms)
Still a little new at rails so I am sure I am just selecting my objects from the parmas incorrectly or something of that nature. Hoping someone can school me a bit on what I am doing wrong on the rails side of things.
-m
What @coreyward says is definitely correct. But i think the error happens even earlier. In the log i see:
Parameters: {"users"=>"[object Object]"}
and Rails does not expects objects, but hashes, so something like
Parameters: {"users"=>"[{:first_name => 'Fred', last_name => 'Kruger'},
{:first_name => "Harrison", :last_name => 'Ford'}]"}
Now, i am not sure how you can do this from flash/flex. Convert to json? But i think that's where you should start looking.
[EDIT: handle the json]
Ah, i can see from your edit that you are now receiving json indeed! Json is actually a string in a special format. That work with that, you need to use the json
gem (add it to your Gemfile
), and then you can write something like:
rcvd_users = JSON.parse(param[:users])
rcvd_users.each do |u|
user = User.find_by_fbid(u[:fbid])
puts u[:fbid]
unless user.nil?
user.update_attributes u
end
end
Hope this helps :)
You're accessing fbid
like it is a method of one of the items in params[:user]
. What you actually want is this:
params[:users].each do |u|
user = User.find_by_fbid(u[:fbid])
user.update_attributes(:first_name => u[:first_name], :last_name => u[:last_name])
end
Assuming that you have NOT prevented mass assignment on the first_name
and last_name
attributes, you can simplify what you're doing to:
params[:users].each do |u|
user = User.find_by_fbid u[:fbid]
user.update_attributes u
end
Just make sure that you have prevented mass assignment on sensitive attributes, like fbid
. You can add this at the top of your model to do this safely (whitelist):
attr_accessible :first_name, :last_name
You should double check your indenting in your source. In your question it's a bit wonky, which can lead to confusion on which end
corresponds to what.
I took @nathanvda advice and and I have Flash send over JSON now. Here is what my consol shows now.
Started POST "/updatethem" for 127.0.0.1 at Sat Jan 22 20:11:51 -0600 2011
Processing by UsersController#update_by_fbid as HTML
Parameters: {"users"=>"[{\"first_name\":\"Joe\",\"last_name\":\"Blow\",\"fbid\":\"93847566\"},{\"first_name\":\"Ronda\",\"last_name\":\"Smith\",\"fbid\":\"7654321\"}]"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE ("users"."fbid" IS NULL) LIMIT 1
Completed 200 OK in 13ms (Views: 2.4ms | ActiveRecord: 0.2ms)
doing a puts params[:users]
does give me the following in the consol
[{"first_name":"Joe","last_name":"Blow","fbid":"93847566"},{"first_name":"Ronda","last_name":"Smith","fbid":"7654321"}]
This looks like an array of users as I would like to send over but doing the following does not seem to iterate over an array. Rails seems to only see params[:users] as a single object and not an array.
params[:users].each do |u|
user = User.find_by_fbid(u[:fbid])
if user.nil?
puts u[:fbid]
else
user.update_attributes u
puts u[:fbid]
end
end
精彩评论