fred
fred

Reputation: 151

Resolving Active record fixture format error

I am trying to test my application and I continually get the following error:

Error:
    ContractsControllerTest#test_should_get_show:
    ActiveRecord::Fixture::FormatError: ActiveRecord::Fixture::FormatError

Error:
    ContractsControllerTest#test_should_get_show:
    NoMethodError: undefined method `each' for nil:NilClass

Below is the code on my contract controller and I have similar code like this on all the controllers.

    def index
      @contract = Contract.all.paginate(page: params[:page], :per_page => 70) 
    end


    def show
      @contract = Contract.find(params[:id])

    end



    def new
       @contract = Contract.new
    end


    def create
         @contract = Contract.new(located)
        if  @contract.save
            flash[:success] = "A record has been successfully added"
        redirect_to contracts_path
        else
          render 'new'
        end
    end



    def located
       params.require(:contract).permit(:contract_name, :contract_status, :services_rendered, :contract_value, :award_year)
    end


       # editing  a record in the contract from cotract table 
     def edit
        @contract = Contract.find(params[:id])
     end





      def update
        @contract = Contract.find(params[:id])
        if @contract.update_attributes(located)
           flash[:success] = "Contract form updated"
           redirect_to contracts_path
        else
           render'edit'
        end
      end



    def destroy
        Contract.find(params[:id]).destroy
        flash[:success] = "A record has been successfully deleted"
        redirect_to contracts_path
    end

Below is the full trace of the error when I run the command rails db:fixtures:load --trace

rails aborted!
ActiveRecord::Fixture::FormatError: ActiveRecord::Fixture::FormatError
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-      
5.0.5/lib/active_record/fixture_set/file.rb:72:in `validate'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-  
5.0.5/lib/active_record/fixture_set/file.rb:49:in `raw_rows'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-    
5.0.5/lib/active_record/fixture_set/file.rb:37:in `config_row'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixture_set/file.rb:27:in `model_class'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:791:in `block (2 levels) in    
read_fixture_files'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-   
5.0.5/lib/active_record/fixture_set/file.rb:15:in `open'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-   
5.0.5/lib/active_record/fixtures.rb:790:in `block in read_fixture_files'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord- 
5.0.5/lib/active_record/fixtures.rb:789:in `each'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:789:in `each_with_object'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:789:in `read_fixture_files'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-   
5.0.5/lib/active_record/fixtures.rb:598:in `initialize'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:529:in `new'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-   
5.0.5/lib/active_record/fixtures.rb:529:in `block (2 levels) in     
create_fixtures'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-  
5.0.5/lib/active_record/fixtures.rb:526:in `map'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:526:in `block in create_fixtures'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
 5.0.5/lib/active_record/connection_adapters/postgresql/referential_integrity.rb:    22:in `disable_referential_integrity'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:523:in `create_fixtures'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord- 
5.0.5/lib/active_record/railties/databases.rake:207:in `block (3 levels) in   
<top        (required)>'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-
5.0.5/lib/rails/commands/rake_proxy.rb:14:in `block in run_rake_task'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-
5.0.5/lib/rails/commands/rake_proxy.rb:11:in `run_rake_task'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties- 
5.0.5/lib/rails/commands/commands_tasks.rb:51:in `run_command!'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-
5.0.5/lib/rails/commands.rb:18:in `<top (required)>'
/home/ubuntu/workspace/final_project/bin/rails:9:in `require'
/home/ubuntu/workspace/final_project/bin/rails:9:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring- 
2.0.2/lib/spring/client/rails.rb:28:in `load'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/client/rails.rb:28:in `call'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/client/command.rb:7:in `call'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-2.0.2/lib/spring/client.rb:30:in    
`run'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-2.0.2/bin/spring:49:in `<top 
(required)>'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-    
2.0.2/lib/spring/binstub.rb:31:in `load'
 /usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/binstub.rb:31:in`<top (required)>'
/home/ubuntu/workspace/final_project/bin/spring:15:in `require'
/home/ubuntu/workspace/final_project/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:fixtures:load
(See full trace by running task with --trace)

My application containts 12 controllers, the same error occurs in each of the controllers. Also, I have 10 tables in my schema some of which contain references / relations to each other.

I don't really know what is wrong and I have be struggling with this problem for about four days now. I would be grateful if anyone could help me with any code or information that could help me to trace the source of the error. I would also be grateful if you could provide information for exactly where I should place the code to trace and solve this error.

Thanks

Upvotes: 2

Views: 2420

Answers (1)

dave_slash_null
dave_slash_null

Reputation: 1124

One of your fixture files in test/fixtures has bad formatting. The problem does not appear to be with your controllers or tests since it is happening for every single one of them. All of the fixtures get loaded into the test database before every single test, even if some are not used for the current test. So if there is an error in one of these files it will get raised for every test.

According to the line from the activerecord source that is throwing the error at the top of the stack trace you've provided, ActiveRecord is expecting every entry in your YAML fixture file to be a key which references a hash.

Each entry in a fixture should represent a model instance. The top level key is used as a name to reference that instance (rails usually names them one and two when generating the fixture template for a new model). Here is an example YAML fixture with one good entry and a few different types of bad ones.

# This will produce a hash associated to key :hash_entry.
# This is the correct type of entry, all others that follow are incorrect for rails fixtures.
hash_entry:
  key1: value1
  key2: value2

# This will produce the string "not a hash" associated to key :string_entry
string_entry: not a hash

# This will produce the array ["also", "not","a","hash"] associated to key :array_entry
array_entry:
  - also
  - not
  - a
  - hash

# This will produce nil associated to key :nil_entry
nil_entry: 

You need to examine your fixtures files in test/fixtures and look for any that have the bad formatting as described above. Here is a rake task that will help you identify which files and entries need to be corrected. First run rails g task fixtures check_format, and place this code inside of the rake file that gets generated at lib/tasks/fixtures.rake.

namespace :fixtures do
  desc "Looks for bad fixture files"
  task check_format: :environment do
    fixtures_dir = Rails.root.join("test", "fixtures")
    fixture_files = Pathname.glob("#{fixtures_dir}/**/*.yml")

    fixture_files.each do |file|
        fixture = YAML.load(IO.read(file))

        fixture.each_pair do |name, entry|
            puts "Bad fixture entry #{name}: #{entry.inspect} in fixture #{file}" unless entry.is_a? Hash
        end
    end
  end
end

Then run rails fixtures:check_format and the offending files and entries will be printed out on the command line for you to find and correct.

Upvotes: 2

Related Questions