Rails 4.2 concern content ignored in test environment
Asked Answered
S

1

5

I'm stuck in a really weird issue. I recently updated from rails 4.1 to 4.2. In 4.1 everything worked fine. But now, in 4.2, it seems model concern content is beig ignored, even if the concern is found.

Putting it simple. I have a Client model which belongs to an Address, relationship that is defined in an Addressable concern:

app/models/client.rb

class Client < ActiveRecord::Base
  include Addressable
end

app/models/address.rb

class Address < ActiveRecord::Base
end

app/models/concerns/addressable.rb

module Addressable
  extend ActiveSupport::Concern

  included do
    belongs_to :address
  end

No problem in development environment. I can do Client.new.address without problems. But in test environment that same line gives me an unknow method address error. If I move belongs_to :address to Client then it works again. The module is being included, because there is no error about this, and if I change the name to Adressabledewdewded then, of course, there is an error.

Same happens with validation methods, etc.

I have been debugging this but I don't find the root. I have copied my development.rb as test.rb and restarted the server but still. I can't reproduce this in a freshly new Rails 4.2 application, so it has to have something to do with my application or the updating process, but no idea where.

Anyone has a clue?

Thanks

UPDATE

This is the stack trace on doing Client.new.address in the console in test environment (in development it works):

NoMethodError: undefined method `address' for #<Client:0xbc89dac0>
    from /home/marc/.gem/ruby/2.1.3/gems/activemodel-4.2.0/lib/active_model/attribute_methods.rb:433:in `method_missing'
    from (irb):3
    from /home/marc/.gem/ruby/2.1.3/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in `start'
    from /home/marc/.gem/ruby/2.1.3/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in `start'
    from /home/marc/.gem/ruby/2.1.3/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in `console'
    from /home/marc/.gem/ruby/2.1.3/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    from /home/marc/.gem/ruby/2.1.3/gems/railties-4.2.0/lib/rails/commands.rb:17:in `<top (required)>'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `require'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `block in require'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `require'
    from /home/marc/projects/clients_webs/a_project/bin/rails:8:in `<top (required)>'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
    from /home/marc/.gem/ruby/2.1.3/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/commands/rails.rb:6:in `call'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/command_wrapper.rb:38:in `call'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/application.rb:183:in `block in serve'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/application.rb:156:in `fork'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/application.rb:156:in `serve'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/application.rb:131:in `block in run'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/application.rb:125:in `loop'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/application.rb:125:in `run'
    from /home/marc/.gem/ruby/2.1.3/gems/spring-1.3.1/lib/spring/application/boot.rb:18:in `<top (required)>'
    from /home/marc/.rubies/ruby-2.1.3/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /home/marc/.rubies/ruby-2.1.3/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'

UPDATE

Result of Client.ancestors in both environments is (without the only difference of instance identity, of course):

 => [Client (call 'Client.connection' to establish a connection), Trader, Addressable, Kaminari::ConfigurationMethods, Kaminari::ActiveRecordModelExtension, Client::GeneratedAssociationMethods, #<#<Class:0xba3b1c70>:0xba3b1d24>, ActiveRecord::Base, Kaminari::ActiveRecordExtension, GlobalID::Identification, ActiveRecord::Store, ActiveRecord::Serialization, ActiveModel::Serializers::Xml, ActiveModel::Serializers::JSON, ActiveModel::Serialization, ActiveRecord::Reflection, ActiveRecord::NoTouching, ActiveRecord::Transactions, ActiveRecord::Aggregations, ActiveRecord::NestedAttributes, ActiveRecord::AutosaveAssociation, ActiveModel::SecurePassword, ActiveRecord::Associations, ActiveRecord::Timestamp, ActiveModel::Validations::Callbacks, ActiveRecord::Callbacks, ActiveRecord::AttributeMethods::Serialization, ActiveRecord::AttributeMethods::Dirty, ActiveModel::Dirty, ActiveRecord::AttributeMethods::TimeZoneConversion, ActiveRecord::AttributeMethods::PrimaryKey, ActiveRecord::AttributeMethods::Query, ActiveRecord::AttributeMethods::BeforeTypeCast, ActiveRecord::AttributeMethods::Write, ActiveRecord::AttributeMethods::Read, ActiveRecord::Base::GeneratedAssociationMethods, #<#<Class:0xb8df1c14>:0xb8df1c50>, ActiveRecord::AttributeMethods, ActiveModel::AttributeMethods, ActiveRecord::Locking::Pessimistic, ActiveRecord::Locking::Optimistic, ActiveRecord::AttributeDecorators, ActiveRecord::Attributes, ActiveRecord::CounterCache, ActiveRecord::Validations, ActiveModel::Validations::HelperMethods, ActiveSupport::Callbacks, ActiveModel::Validations, ActiveRecord::Integration, ActiveModel::Conversion, ActiveRecord::AttributeAssignment, ActiveModel::ForbiddenAttributesProtection, ActiveRecord::Sanitization, ActiveRecord::Scoping::Named, ActiveRecord::Scoping::Default, ActiveRecord::Scoping, ActiveRecord::Inheritance, ActiveRecord::ModelSchema, ActiveRecord::ReadonlyAttributes, ActiveRecord::Persistence, ActiveRecord::Core, Object, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject]

And doing Client.reflections.keys makes address to appear in development but not in test.

Skip answered 13/2, 2015 at 10:48 Comment(10)
Could you add a complete stack trace of the error occurring, as well as the test in question where the error occurs?Kingsly
Hey @Kingsly . There is no need of test to reproduce this in my application. Just opening the console in test environment and doing Client.new.address raises a undefined method address'` error. I edit the answer to add the stack trace, but I'm afraid it is completely useless.Skip
You're right, that makes the point moot. Sorry I missed that. Can you run Client.ancestors in both a dev and test console, and see if the Adressable module is present in both?Kingsly
Thanks @janfoeh. In both cases Addressable appears... I update the question with its output.Skip
Hmm. Client.reflections allows you to inspect the associations, with Client.reflections.keys giving you only the names. Can you spot a difference there between both environments?Kingsly
Yes, address appears in development but not in test :)Skip
I'm quite sorry, but I'm at a loss. What I would do next is install a debugger (debugger for Ruby 1.x, byebug for Ruby 2.x), set a breakpoint before the belongs_to and step through it in both environments.Kingsly
Yes, I did, but nothing clear. Thank you very much anyway @janfoechSkip
@Kingsly I got it :) If you are wondering which was the reason read my answer )Skip
Good catch, and a good reminder for me to namespace my Concerns. I honestly wish they were by default.Kingsly
S
9

I got it. The thing is that a gem that is present only in my test environment (json-schema), has addressable gem as a dependency, which is defining an Addressable module. When Rails tries to autoload Addressable it finds the class defined by addressable instead of my concern class. The module is being included but it is not the one I thought.

When updating my Gemfile, json-schema has been updated and now depends on addresable, since November 2014.

Hard one to catch :)

Skip answered 13/2, 2015 at 14:22 Comment(2)
I've been banging my head against the wall for an hour with exactly the same issue, thank you for posting the solution!Binnie
Daaaaaaaaammit. I've spent all day with the exact problem -- a concern named "Addressable" that works fine, except in test environment. After I stumble across this issue, then go eyeball my Gemfile.lock, and I find an "addressable" gem being required by the capybara gem, which is only included in test. Ugh! I've been troubleshooting my RSpec all damn day!Allocate

© 2022 - 2024 — McMap. All rights reserved.