Why am I getting this "undefined" error in a callback to a Rails model by passing a method as a character?

I have a class called Mail that needs to convert its labeling content to HTML when it is modified or it has not yet been converted. I try to use the before_save callback with an argument if:, but I get this error for everything I pass ifwhen I try to run my tests:

Testing started at 1:55 ... rake aborted!
undefined method 'markdown_changed_or_html_nil?' for #<Post:0x000000053603d0>C: /Users/user/Documents/GitHub/jw/app/models/post.rb: 7: in <class:Post>C: /Users/user/Documents/GitHub/jw/app/models/post.rb: 1: in <top (required)>C : /Users/user/Documents/GitHub/jw/test/test_helper.rb: 12: in <class:TestCase>C: /Users/user/Documents/GitHub/jw/test/test_helper.rb: 5: in <top (required)>C: / Users / user / Documents / GitHub / jw / test / models / post_test.rb: 1: in <top (required)>
-e: 1: in 'load'
-e: 1: in '' Tasks: TOP => test: run => test: units (see full trace by completing the task with --trace) Startup options: --seed 13458

# Current tests:

Ready tests in 0.002000s, 0.0000 tests / s, 0.0000 statements / s.

0 tests, 0 statements, 0 errors, 0 errors, 0 omissions

1

:

class Post < 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

Ruby 2.0.0 Rails 4.0.2.

- Rails.


: post_test.rb

require 'test_helper'

class PostTest < 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 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 '<p>I got some <em>sick</em> markdown</p>', new_post.content_html
  end
end
+4
2

( , , ), changed? . changed? , . :

def markdown_changed_or_html_nil?
  # based on your method name, shouldn't this be:
  # content_markdown_changed? || content_html.nil?
  content_markdown_changed? || content_markdown.nil?
end

Dirty http://api.rubyonrails.org/classes/ActiveModel/Dirty.html.

, Rails 4 Dirty ActiveRecord::Base, include ActiveModel::Dirty .

:

validates :user, :title, :content_markdown, { presence: true, on: create }

:

validates :user, :title, :content_markdown, { presence: true, on: :create }
+3

validates :user, :title, :content_markdown, { presence: true, on: create }

validates :user, :title, :content_markdown, presence: true, on: :create

, ruby ​​ validates :user, :title, :content_markdown validates. , , , "" . linenumbers CaptChrisD , .

+2

Source: https://habr.com/ru/post/1543065/


All Articles