Skip to content

Instantly share code, notes, and snippets.

@javmorin
Created January 22, 2011 02:09
Show Gist options
  • Save javmorin/790783 to your computer and use it in GitHub Desktop.
Save javmorin/790783 to your computer and use it in GitHub Desktop.
sample code which causes strange model interaction with multiple inheritance
class Example
include Mongoid::Document
field :example_val
class Holder < HolderBase
embeds_one :item, :class_name => "Example"
end
end
class ExampleHolder < HolderBase
embeds_one :example
end
class HolderBase
include Mongoid::Document
field :holder_val
end
e = Example.new(:example_val => "Example String")
=> #<Example _id: 4d3a398da435fd762a000002, example_val: "Example String">
e.save
=> true
e_h = Example::Holder.new(:item => e.clone)
=> #<Example::Holder _id: 4d3a39a5a435fd762a000004, holder_val: nil>
e_h.save
e_h.relations
=> {"example"=>#<Mongoid::Relations::Metadata
class_name: Example,
cyclic: No,
dependent: None,
inverse_of: N/A,
inverse_setter: =,
inverse_type: N/A,
inverse_type_setter: N/A,
key: example,
macro: embeds_one,
name: example,
polymorphic: No,
relation: Mongoid::Relations::Embedded::One,
setter: example=>
, "item"=>#<Mongoid::Relations::Metadata
class_name: Example,
cyclic: No,
dependent: None,
inverse_of: N/A,
inverse_setter: =,
inverse_type: N/A,
inverse_type_setter: N/A,
key: item,
macro: embeds_one,
name: item,
polymorphic: No,
relation: Mongoid::Relations::Embedded::One,
setter: item=>
}
e_h.save
NoMethodError: undefined method `example' for #<Example::Holder _id: 4d3a39a5a435fd762a000004, holder_val: nil>
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/attributes.rb:75:in `method_missing'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/document.rb:199:in `send'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/document.rb:199:in `to_hash'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/document.rb:198:in `each'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/document.rb:198:in `to_hash'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/document.rb:197:in `tap'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/document.rb:197:in `to_hash'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/persistence/insert.rb:48:in `insert'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/persistence/insert.rb:30:in `persist'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:413:in `_run_save_callbacks'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:93:in `send'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:93:in `run_callbacks'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/persistence/insert.rb:29:in `persist'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:413:in `_run_create_callbacks'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:93:in `send'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:93:in `run_callbacks'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/persistence/insert.rb:28:in `persist'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/persistence.rb:45:in `insert'
from /home/mikej/.rvm/gems/ruby-1.8.7-p302@global/gems/mongoid-2.0.0.rc.6/lib/mongoid/persistence.rb:145:in `save'
from (irb):13
@javmorin
Copy link
Author

removing the example_holder.rb file, allows things to work correctly with no further changes.

@javmorin
Copy link
Author

One further note.. if the inheritance on HolderBase is removed, things work just fine as well. My first attempt to reproduce the issue didn't reproduce the bug for that very reason. So it's the creative inheritance involved which trips things up.

@durran
Copy link

durran commented Jan 23, 2011

Thanks for the gist... This is an odd way of modeling things to me, but the first thing I can see is Example needs an embedded_in defined... But I'll need to mess around with this a bit to see what exactly needs to be done.

@durran
Copy link

durran commented Jan 23, 2011

And yeah this is also another class_attribute issue I believe.

@javmorin
Copy link
Author

agreed, this is an odd setup, and it didn't stay that way, it was the result of artifacts to a refactoring process.

Another thing to check would be if it generates the same behavior if there is two (or more) classes which inherit from HolderBase of either a nested or non-nested type. It's possible the naming doesn't matter, but the number of things that inherit from a common base class. I don't have the time to test this today though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment