<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -232,6 +232,10 @@ module ActiveRecord
     def method_missing(method_id, *args, &amp;block)
       method_name = method_id.to_s
 
+      if self.class.private_method_defined?(method_name)
+        raise NoMethodError(&quot;Attempt to call private method&quot;, method_name, args)
+      end
+
       # If we haven't generated any methods yet, generate them, then
       # see if we've created the method we're looking for.
       if !self.class.generated_methods?
@@ -334,10 +338,12 @@ module ActiveRecord
     # &lt;tt&gt;person.respond_to?(:name=)&lt;/tt&gt;, and &lt;tt&gt;person.respond_to?(:name?)&lt;/tt&gt;
     # which will all return +true+.
     alias :respond_to_without_attributes? :respond_to?
-    def respond_to?(method, include_priv = false)
+    def respond_to?(method, include_private_methods = false)
       method_name = method.to_s
       if super
         return true
+      elsif self.private_methods.include?(method_name) &amp;&amp; !include_private_methods
+        return false
       elsif !self.class.generated_methods?
         self.class.define_attribute_methods
         if self.class.generated_methods.include?(method_name)</diff>
      <filename>activerecord/lib/active_record/attribute_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -58,19 +58,19 @@ class AttributeMethodsTest &lt; ActiveRecord::TestCase
 
   def test_kernel_methods_not_implemented_in_activerecord
     %w(test name display y).each do |method|
-      assert_equal false, ActiveRecord::Base.instance_method_already_implemented?(method), &quot;##{method} is defined&quot;
+      assert !ActiveRecord::Base.instance_method_already_implemented?(method), &quot;##{method} is defined&quot;
     end
   end
 
   def test_primary_key_implemented
-    assert_equal true, Class.new(ActiveRecord::Base).instance_method_already_implemented?('id')
+    assert Class.new(ActiveRecord::Base).instance_method_already_implemented?('id')
   end
 
   def test_defined_kernel_methods_implemented_in_model
     %w(test name display y).each do |method|
       klass = Class.new ActiveRecord::Base
       klass.class_eval &quot;def #{method}() 'defined #{method}' end&quot;
-      assert_equal true, klass.instance_method_already_implemented?(method), &quot;##{method} is not defined&quot;
+      assert klass.instance_method_already_implemented?(method), &quot;##{method} is not defined&quot;
     end
   end
 
@@ -80,7 +80,7 @@ class AttributeMethodsTest &lt; ActiveRecord::TestCase
       abstract.class_eval &quot;def #{method}() 'defined #{method}' end&quot;
       abstract.abstract_class = true
       klass = Class.new abstract
-      assert_equal true, klass.instance_method_already_implemented?(method), &quot;##{method} is not defined&quot;
+      assert klass.instance_method_already_implemented?(method), &quot;##{method} is not defined&quot;
     end
   end
 
@@ -228,6 +228,40 @@ class AttributeMethodsTest &lt; ActiveRecord::TestCase
     assert_equal [:field_b], Minimalistic.skip_time_zone_conversion_for_attributes 
   end
 
+  def test_read_attributes_respect_access_control
+    privatize(&quot;title&quot;)
+
+    topic = @target.new(:title =&gt; &quot;The pros and cons of programming naked.&quot;)
+    assert !topic.respond_to?(:title)
+    assert_raise(NoMethodError) { topic.title }
+    topic.send(:title)
+  end
+
+  def test_write_attributes_respect_access_control
+    privatize(&quot;title=(value)&quot;)
+
+    topic = @target.new
+    assert !topic.respond_to?(:title=)
+    assert_raise(NoMethodError) { topic.title = &quot;Pants&quot;}
+    topic.send(:title=, &quot;Very large pants&quot;)
+  end
+
+  def test_question_attributes_respect_access_control
+    privatize(&quot;title?&quot;)
+
+    topic = @target.new(:title =&gt; &quot;Isaac Newton's pants&quot;)
+    assert !topic.respond_to?(:title?)
+    assert_raise(NoMethodError) { topic.title? }
+    assert topic.send(:title?)
+  end
+
+  def test_bulk_update_respects_access_control
+    privatize(&quot;title=(value)&quot;)
+
+    assert_raise(ActiveRecord::UnknownAttributeError) { topic = @target.new(:title =&gt; &quot;Rants about pants&quot;) }
+    assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title =&gt; &quot;Ants in pants&quot; } }
+  end
+
   private
   def time_related_columns_on_topic
     Topic.columns.select{|c| [:time, :date, :datetime, :timestamp].include?(c.type)}.map(&amp;:name)
@@ -244,4 +278,13 @@ class AttributeMethodsTest &lt; ActiveRecord::TestCase
     Time.zone = old_zone
     ActiveRecord::Base.time_zone_aware_attributes = old_tz
   end
+
+  def privatize(method_signature)
+    @target.class_eval &lt;&lt;-private_method
+      private
+      def #{method_signature}
+        &quot;I'm private&quot;
+      end
+    private_method
+  end
 end</diff>
      <filename>activerecord/test/cases/attribute_methods_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>a78ec93036644c41f936128a2b6d52f3136ad64c</id>
    </parent>
  </parents>
  <author>
    <name>Adam Milligan</name>
    <email>adam@theophrastus.local</email>
  </author>
  <url>http://github.com/rails/rails/commit/4d9a7ab5f5c28820e0b076f9ca44bdd20e19e6ea</url>
  <id>4d9a7ab5f5c28820e0b076f9ca44bdd20e19e6ea</id>
  <committed-date>2008-09-24T10:40:07-07:00</committed-date>
  <authored-date>2008-09-21T01:03:09-07:00</authored-date>
  <message>Changed ActiveRecord attributes to respect access control.

Signed-off-by: Michael Koziarski &lt;michael@koziarski.com&gt;
[#1084 state:committed]</message>
  <tree>2fbd6389b39e962d3233df236eb5f6344264454b</tree>
  <committer>
    <name>Michael Koziarski</name>
    <email>michael@koziarski.com</email>
  </committer>
</commit>
