Open maxim opened 15 years ago
Since it's almost impossible to find out in which context you're calling trust (except maybe looking at Kernel#caller and relying on rails directory structure conventions) - maybe it's best to add a config option to disable attr_accessible requirement for all models.
I ran into this problem in a project where I was using acts-as-taggable-on. It uses constructs like this: Tagging.create(:tag_id => new_tag.id, :context => tag_type, :taggable => self, :tagger => owner)
to create various records.
I've patched acts-as-taggable-on (http://github.com/mbleigh/acts-as-taggable-on/commit/f3bf4e743722f191b7c08090bfc49f8b3513e1b0), so it sets attr_accessible, but this could break apps where the Tag/Tagging are extended with custom attributes (I have, for instance, a application where I add a position column to Tagging's).
At first I thought forcing attr_accessible was a good thing, but now I'm not so sure. I think a config option is probably best.
I ran into this issue with the vestal_versions gem. The solution for me was to add attr_accessible to the versions model in an initializer. (/config/initializers/vestal_versions_override.rb):
VestalVersions::Version.class_eval do
attr_accessible :all
end
Take delayed_job for example. It sets priority and other metadata to its internal Delayed::Job model. Of course this causes an error, unless I add .trust to its hashes or set attr_accessible :all on delayed job's model. I've been thinking about a way to work around that, and found that the only reasonable place to guard against external params is in controllers. Maybe it makes sense to explicitly check where method #trusted? is being called, and always return true unless its context is_a?(ActionController::Base). Everywhere else you're pretty much on your own - since developer should be allowed to freely exchange params internally. If someone sets user-supplied attributes anywhere but in their controller - well then ... they suck.