Raven Raven - 5 months ago 41
Ruby Question

FactoryGirl Rails Argument error

I am having a weird problem / error with FactoryGirl on Rails:

ArgumentError: wrong number of arguments (given 1, expected 0)
/Users/bintoy/ruby-apps/tradegecko-exercise/exercise-app/spec/factories/object_records.rb:3:in `object_id'


Note: This is not a duplicate question from this: Why am I getting FactoryGirl wrong number of arguments error? - Also I already tried a lot of possible solutions like manually loading or noticing the problem with FactoryGirls and Spring. But none of them worked.

The setup is that the database is based on MongoDB (Mongoid mapper) and here are the involved files:

app/models/object_record.rb

class ObjectRecord
include Mongoid::Document

validates_presence_of :object_id, :object_type, :timestamp, :object_changes
validates_uniqueness_of :timestamp, :scope => [:object_id, :object_type]

field :object_id, type: Integer
field :object_type, type: String
field :timestamp, type: DateTime
field :object_changes, type: Hash

end


spec/features/user_searches_spec.rb

require 'spec_helper'
require 'rails_helper'

feature 'User searches on table' do
before :each do
FactoryGirl.create(:object_record)
end

scenario 'with an object id', js: true do
input_a_search '1'

expect(page).to have_css(".sorting_1", :text => "1")
save_and_open_screenshot

end

def input_a_search(search_word)
visit object_records_index_path
find('input[type=search]').set(search_word)
end
end


spec/factories/object_records.rb

FactoryGirl.define do
factory :obect_record do
object_id 1
object_type "ObjectA"
timestamp 1465748715
object_changes ({:property1 => "val1"})
end
end


spec/support/factory_girl.rb

RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end


spec/spec_helper.rb

RSpec.configure do |config|

config.after(:all) do
DatabaseCleaner.clean_with(:truncation)
end

config.before(:suite) do
FactoryGirl.reload
end


config.expect_with :rspec do |expectations|

expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

config.mock_with :rspec do |mocks|

mocks.verify_partial_doubles = true
end

end


spec/rails_helper.rb

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

abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'

require 'capybara/rspec'
require 'capybara/rails'

require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist

require 'factory_girl_rails'


Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

RSpec.configure do |config|
config.include Capybara::DSL

config.infer_spec_type_from_file_location!

config.filter_rails_from_backtrace!

end


EDIT:
Out of just a random trying to debug this, I tried omitting the argument for object_id in the factory to see what happens:

FactoryGirl.define do
factory :obect_record do
object_id
...


But instead I got this Failure/Error message from Rspec:

1) User searches on table with an object id
Failure/Error: FactoryGirl.create(:object_record)

ArgumentError:
Factory not registered: object_record
# ./spec/features/user_searches_spec.rb:8:in `block (2 levels) in <top (required)>'

Answer

There is an existing object_id method in ruby: your factory is calling that method, rather than falling through to the method_missing code in factory girl that creates an attribute.

The method missing hook is just a convenience, you can add attributes directly by calling

add_attribute :object_id, 1

In addition your factory definition appears to have a typo (obect_record).

Because object_id is a core ruby method, it's not impossible that you'll run into other issues as a result of using that name.