This project is archived and is in readonly mode.
Rails 3 has_many through forces developer to make *_id attributes unprotected
Reported by Pawel | March 9th, 2011 @ 09:15 PM
In the classic Group <-> Membership <-> User scenario:
class Group
has_many :memberships
has_many :users, :through => :memberships
end
class Membership
belongs_to :user
belongs_to :group
end
class User
has_many :memberships
end
If Membership has:
attr_protected :user_id, :group_id
Then executing:
group = Group.create!
user = User.create!
group.users << user
group.users.include? user # => true
group.users.reload.include? user # => false
Causes membership creation to fail.
From my research, it appears this is due to new way of creating
"through" models in Rails 3.
Through models are now created using mass-assignment.
The problem lies in ActiveRecord::Associations::HasManyThroughAssociation#insert_record method defined in lib/active_record/associations/has_many_through_association.rb file.
Here is a quick monkey patch which resolves the issue (put it in config/initializers/fix_has_many.rb):
class ActiveRecord::Associations::HasManyThroughAssociation
protected
def insert_record(record, force = true, validate = true)
if record.new_record?
if force
record.save!
else
return false unless record.save(:validate => validate)
end
end
through_association = @owner.send(@reflection.through_reflection.name)
through_association.create! do |r|
construct_join_attributes(record).each { |k, v| r.send "#{k}=", v }
end
end
end
Comments and changes to this ticket
-
Dan Pickett March 12th, 2011 @ 05:41 PM
- Tag changed from activerecord rails3 has_many through mass-assignment security attr_accessible to attr_accessible, has_many_through_association, rails3
- State changed from new to open
- Assigned user set to Dan Pickett
- Importance changed from to Low
based on my reading of the code on edge in has_many_through association it is performing a direct assignment on both ends of the relationship and the assignment should be unaffected by attr security.
Can you provide a failing test case for this, Pawel?
-
Pawel March 15th, 2011 @ 12:53 PM
I was testing this only on 3.0.5.
From reading the edge source code it appears to be fixed, so the bug could be closed now. -
Dan Pickett March 15th, 2011 @ 12:57 PM
- State changed from open to resolved
-
Dan Pickett April 6th, 2011 @ 11:16 AM
Dmitry,
Could you provide a failing test case? I'd be happy to look into it.
Thanks,
Dan -
dmitry zhelnin April 7th, 2011 @ 02:57 PM
Yes, this test case fails for me:
https://github.com/whitered/mass_assignment_protection/blob/master/...
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>