title: Why do I get this "undefined method" error in a Rails model callback, passing the method as a symbol?
body: <p>I have a class called "Post" that should convert its markdown content to HTML when it is changed or it hasn't been converted yet. I'm trying to use the before_save callback with the <code>if:</code> argument, but I get this error on whatever I pass to the <code>if</code> when I try to run my tests:</p>
  
  <blockquote>
    <p>Testing started at 1:55 ... rake aborted!<br>
    undefined method 'markdown_changed_or_html_nil?' for <code>#&lt;Post:0x000000053603d0&gt;</code>
    C:/Users/user/Documents/GitHub/jw/app/models/post.rb:7:in <code>&lt;class:Post&gt;</code>
    C:/Users/user/Documents/GitHub/jw/app/models/post.rb:1:in <code>&lt;top (required)&gt;</code>
    C:/Users/user/Documents/GitHub/jw/test/test_helper.rb:12:in <code>&lt;class:TestCase&gt;</code>
    C:/Users/user/Documents/GitHub/jw/test/test_helper.rb:5:in <code>&lt;top (required)&gt;</code>
    C:/Users/user/Documents/GitHub/jw/test/models/post_test.rb:1:in <code>&lt;top (required)&gt;</code><br>
    -e:1:in 'load'<br>
    -e:1:in '' Tasks: TOP => test:run => test:units (See full trace by running task with --trace) Run options: --seed 13458</p>
    
    <p># Running tests:</p>
    
    <p>Finished tests in 0.002000s, 0.0000 tests/s, 0.0000 assertions/s.</p>
    
    <p>0 tests, 0 assertions, 0 failures, 0 errors, 0 skips</p>
    
    <p>Process finished with exit code 1</p>
  </blockquote>
  
  <p>This is the model in question:</p>
  
  <pre><code>class Post &lt; ActiveRecord::Base
    include ActiveModel::Dirty
  
    before_save :convert_markdown, if: :markdown_changed_or_html_nil?
  
    belongs_to :user
    validates :user, :title, :content_markdown, { presence: true, on: create }
    validates_associated :user
  
    protected
      def convert_markdown
        markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, space_after_headers: true, underline: true)
        self.content_html = markdown.render(content_markdown)
      end
  
      def markdown_changed_or_html_nil?
        content_markdown.changed? || content_markdown.nil?
      end
  end
  </code></pre>
  
  <p>I'm using Ruby 2.0.0 and Rails 4.0.2.</p>
  
  <p>I might well have made a really really basic mistake - I'm still learning Rails.</p>
  
  <hr>
  
  <p>Edit: this is post_test.rb</p>
  
  <pre><code>require 'test_helper'
  
  class PostTest &lt; ActiveSupport::TestCase
    test 'saving an empty object fails' do
      new_post = Post.new
  
      assert_not new_post.save
    end
  
    test 'validates that given user id corresponds to user' do
      # This will create a user with a given id so we can use the next one up
      test_user = User.create({ name: 'Johnny Test', email: 'johnny.test@example.com',
                              password: 'password', password_confirmation: 'password' })
  
      # Use next id up - there's no reason it should be taken at this point
      given_user_id = test_user.id + 1
  
      post_with_invalid_user = Post.new({ title: 'Look at my glorious title', content_markdown: 'Sick content',
                                        user_id: given_user_id })
  
      assert_not post_with_invalid_user.save
    end
  
    test 'converts markdown into html' do
      # This is a really really basic test just to make sure a conversion happens
      new_post = Post.new({ title: 'Check out this markdown, baby', content_markdown: 'I got some *sick* markdown',
                          user_id: users(:paul).id })
  
      assert_equal '&lt;p&gt;I got some &lt;em&gt;sick&lt;/em&gt; markdown&lt;/p&gt;', new_post.content_html
    end
  end
  </code></pre>