Search code examples
ruby-on-railsreform

Uninitialized constant ArticleFormTest::Article in Reform gem tutorial


I'm working through a tutorial on the reform gem, but running into an error.

Source: http://culttt.com/2016/02/10/using-form-objects-in-ruby-on-rails-with-reform/

Error:

NameError: uninitialized constant ArticleFormTest::Article test/forms/article_form_test.rb:8:in `setup'

My understanding is that this results from @model = Article.new in below:

require 'test_helper'

class ArticleFormTest < ActiveSupport::TestCase
    def setup
        @model = Article.new
        @form = ArticleForm.new(@model)
    end

    test "should require title" do
        @form.validate({})
        assert_includes(@form.errors[:title], "can\'t be blank")
    end
end

I've setup article_form.rb, (see below). So I'm not sure why this is happening.

require "reform/form/validation/unique_validator.rb"

class ArticleForm < Reform::Form
    property :title,        presence: true, unique: true
    property :markdown,     presence: true
    property :published_at, presence: true
    property :user,         presence: true
end

Can anyone advise what I might be doing wrong?

UPDATE

Below added per request.

test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
end

Solution

  • This is your clue: ArticleFormTest::Article

    Since it can't find Article class defined anywhere, it assumes that it is namespaced somewhere in your current class - which it is not. So system throws an error. You need to let your test know where Article model is defined or define it in a test (I would highly recommend against it - keep your definitions in one place, unless you can justify creating a separate definition just for the test.)

    To your comment:

    "Also, I didn't think I needed article.rb file as the purpose of reform is to decouple forms from models.. am I incorrect?"

    You still need a model to supply to the form for it to process. Reform is just a specialized type of object - a form object, that knows what to do with a model, but it still needs a model. Decoupling here refers to the fact that your model only deals with persistence (writing & saving to storage (DB, hard drive, memory) and maybe some lookup scopes). Reform or Form Objects, orchestrate how data gets validated and inserted in to a model or multiple models.

    Models are really good at modeling data storage, but not always good at getting input from real world users/systems. That's the purpose for Form Objects / Reform gem. And also to make models more manageable.

    One more thing to emphasize, that may come in useful one day: Reform - doesn't care what model is . It's just a plain ruby object as far as Reform is concerned. It means Reform doesn't care if the model is backed by a DB, a text file, a temporary object that deals with a graphics file, whatever. Especially if you use dry-rb/dry-validations, and not ActiveModel validations, it doesn't even need to know what ORM you are using.

    Hope this helps.