views:

458

answers:

2

I have a question about using attr_accessible in Rails.

I sometimes want to set guard_protected_attributes to false in order to bypass mass assignment protection. I'm wondering why the following line doesn't work (it creates the "can't stringify keys" error):

@user.attributes=({ :name => "James Bond", :admin => true }, false)

...but this does:

@user.send(:attributes=, { :name => "James Bond", :admin => true }, false)

Anyone know the reason?

+4  A: 

Because the Ruby parser parses '{ :name => "James Bond", :admin => true}, false' as the single argument to #attributes=. Calling a method 'foo=' limits you to one argument in Ruby. The send gets around that.

What's actually happening is that Rails is trying to stringify the keys of false, which, being a FalseClass rather than a Hash, doesn't have any.

James A. Rosen
Thanks, this was driving me crazy!
fig
I actually ran some tests in IRB. The single argument is an Array, which also can't stringify its keys.
James A. Rosen
Just once I'd like to see an array stringify its keys.
fig
OK, Dave: Array.class_eval { def stringify_keys; result = {}; each_with_index { |x,i| reuslt["#{i}"] = x }; result }. But I personally don't have a use for it :)
James A. Rosen
A: 

I want to see if you guys would follow up this, so I have to use .send or if there is a better approach?

goodwill