{"action":"created","issue":{"url":"https://api.github.com/repos/thoughtbot/factory_girl/issues/885","repository_url":"https://api.github.com/repos/thoughtbot/factory_girl","labels_url":"https://api.github.com/repos/thoughtbot/factory_girl/issues/885/labels{/name}","comments_url":"https://api.github.com/repos/thoughtbot/factory_girl/issues/885/comments","events_url":"https://api.github.com/repos/thoughtbot/factory_girl/issues/885/events","html_url":"https://github.com/thoughtbot/factory_girl/issues/885","id":141844110,"number":885,"title":"Inherited traits fail noisily when a trait has the same name as another factory","user":{"login":"georgemillo","id":2656485,"avatar_url":"https://avatars.githubusercontent.com/u/2656485?v=3","gravatar_id":"","url":"https://api.github.com/users/georgemillo","html_url":"https://github.com/georgemillo","followers_url":"https://api.github.com/users/georgemillo/followers","following_url":"https://api.github.com/users/georgemillo/following{/other_user}","gists_url":"https://api.github.com/users/georgemillo/gists{/gist_id}","starred_url":"https://api.github.com/users/georgemillo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/georgemillo/subscriptions","organizations_url":"https://api.github.com/users/georgemillo/orgs","repos_url":"https://api.github.com/users/georgemillo/repos","events_url":"https://api.github.com/users/georgemillo/events{/privacy}","received_events_url":"https://api.github.com/users/georgemillo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-03-18T11:43:18Z","updated_at":"2016-03-21T16:06:19Z","closed_at":null,"body":"From https://github.com/thoughtbot/factory_girl/issues/360, I learned that I can create traits that inherit from other traits, which is great. But when I tried to use this in my own app, I couldn't get it to work and kept getting a `NoMethodError`. Eventually I figured out it was because the trait I was inheriting from had the same name as one of my other factories, which was causing a subtle and unintuitive failure.\r\n\r\nHere's a slightly contrived example that demonstrates what I mean. Run this script and it will fail with `NoMethodError: undefined method `present=' for #<Employee>`\r\n\r\n```ruby\r\nbegin\r\n  require 'bundler/inline'\r\nrescue LoadError => e\r\n  $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'\r\n  raise e\r\nend\r\n\r\ngemfile(true) do\r\n  source 'https://rubygems.org'\r\n  gem 'rails', '>= 5.0.0.beta3', '< 5.1'\r\n  gem 'sqlite3'\r\n  gem 'factory_girl_rails', '~> 4.6.0'\r\nend\r\nrequire 'active_record'\r\nrequire 'minitest/autorun'\r\nrequire 'logger'\r\nrequire 'factory_girl'\r\n\r\n# Ensure backward compatibility with Minitest 4\r\nMinitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)\r\n\r\n# This connection will do for database-independent bug reports.\r\nActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')\r\nActiveRecord::Base.logger = Logger.new(STDOUT)\r\n\r\nActiveRecord::Schema.define do\r\n  create_table :presents, force: true do |t|\r\n    t.integer :price\r\n    t.boolean :wrapped\r\n  end\r\n\r\n  create_table :employees, force: true do |t|\r\n    t.datetime :arrived_at\r\n    t.boolean  :on_break, default: true\r\n  end\r\nend\r\n\r\nclass Present < ActiveRecord::Base\r\nend\r\n\r\nclass Employee < ActiveRecord::Base\r\nend\r\n\r\nFactoryGirl.define do\r\n  factory :present do\r\n    price   14_99\r\n    wrapped true\r\n  end\r\n\r\n  factory :employee do\r\n    trait :present do\r\n      arrived_at { 5.hours.ago }\r\n    end\r\n\r\n    trait :working do\r\n      present\r\n      on_break false\r\n    end\r\n  end\r\nend\r\n\r\nclass BugTest < Minitest::Test\r\n\r\n  def test_factory_traits\r\n    FactoryGirl.create :employee, :working # This line raises an error\r\n    assert_equal Employee.count, 1\r\n    employee = Employee.last\r\n    assert (employee.arrived_at < Time.now)\r\n    refute employee.on_break\r\n  end\r\nend\r\n```\r\n\r\nIs there any logical reason why trait names and factory names shouldn't conflict? If there isn't, can the above code be made to work? If there is, can things be changed so that, in my above example, trying to define the trait `:present` will raise a more helpful error, like how when I try to define a *factory* whose name has been taken I get an error that says `factory already defined`?"},"comment":{"url":"https://api.github.com/repos/thoughtbot/factory_girl/issues/comments/199358253","html_url":"https://github.com/thoughtbot/factory_girl/issues/885#issuecomment-199358253","issue_url":"https://api.github.com/repos/thoughtbot/factory_girl/issues/885","id":199358253,"user":{"login":"georgemillo","id":2656485,"avatar_url":"https://avatars.githubusercontent.com/u/2656485?v=3","gravatar_id":"","url":"https://api.github.com/users/georgemillo","html_url":"https://github.com/georgemillo","followers_url":"https://api.github.com/users/georgemillo/followers","following_url":"https://api.github.com/users/georgemillo/following{/other_user}","gists_url":"https://api.github.com/users/georgemillo/gists{/gist_id}","starred_url":"https://api.github.com/users/georgemillo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/georgemillo/subscriptions","organizations_url":"https://api.github.com/users/georgemillo/orgs","repos_url":"https://api.github.com/users/georgemillo/repos","events_url":"https://api.github.com/users/georgemillo/events{/privacy}","received_events_url":"https://api.github.com/users/georgemillo/received_events","type":"User","site_admin":false},"created_at":"2016-03-21T16:06:19Z","updated_at":"2016-03-21T16:06:19Z","body":"Thanks for the feedback. Just to clarify, when you say:\r\n\r\n> What probably makes more sense is an explicit failure if a factory and trait are ever named the same thing, regardless of nesting.\r\n\r\nAre you talking about raising an error at the point where the factory is *defined*, or when the factory/trait is *called*? If it's the former, aren't you contradicting yourself? Because that's what I was trying to suggest when I said:\r\n\r\n> can things be changed so that, in my above example, trying to define the trait :present will raise a more helpful error\r\n\r\nto which you said \"I don't believe so\". (Apologies if my original wording wasn't clear enough.)\r\n\r\nCan you clarify?\r\n\r\nThanks\r\n\r\n\r\n"}}