
DataMapper::Base class inside another class doesn't work
Reported by Jan Molic | April 30th, 2008 @ 07:29 AM
This doesn't work as expected, because it is inside a Foo class:
class Foo
class Author < DataMapper::Base
has_many :articles
end
class Article < DataMapper::Base
belongs_to :author
end
end
------
I looked for a solution, found two problems:
1. in associations/has_n_association.rb
1.1. There is a problem with Kernel.get_const() in associated_constant(). It expect only "Foo" or "Author", but fails when get "Foo::Author".
The solution is to split the string constant by :: and start from the top Object:
def associated_constant
@associated_constant || begin
klass = Object
associated_constant_name.to_s.split( /::/ ).each { |const_name|
const_name = const_name.to_sym
if klass.const_defined?( const_name )
klass = klass.const_get( const_name )
else
raise "constant #{klass.to_s}::#{const_name} missing"
end
}
@associated_constant = klass
end
end
1.2. Then if :class or :class_name is not defined, associated_constant_name() guess it from @association_name. This works when Article or Author is the top class, but not if it is inside Foo. The solution could be to use the same parent classes as the @constant and guess it like this
def associated_constant_name
#...
else
@associated_constant_name = @constant.to_s.split( /::/ )[0..-2].join( '::' ) + '::' + Inflector.classify (@association_name)
end
#...
end
2. in dependency_queue.rb
In resolve! there is the same problem as in 1.1. The solution could be again to start from the top:
def resolve!
@dependencies.each_pair do |class_name, callbacks|
klass = Object
class_name.split( /::/ ).each { |const_name|
const_name = const_name.to_sym
if klass.const_defined?( const_name )
klass = klass.const_get( const_name )
else
raise "constant #{klass.to_s}::#{const_name} missing"
end
}
# klass found
callbacks.each do |b|
b.call(klass)
end
callbacks.clear
end
end
Maybe it would be better to create Object.full_const_get() which could resolve 'Foo::Author' (I think it is in more places)
Comments and changes to this ticket
-
Sam Smoot May 2nd, 2008 @ 04:34 AM
- Assigned user set to Scott Bauer
Nested constants won't be fully back-ported to 0.3.x, but is targeted for resolution in 0.9.x. Some specs have already been written and updates made.
If you would like to submit a patch I will be happy to apply it to 0.3.x though.
In the mean-time, we can make the simple change you suggest above.
Scott, please back-port http://github.com/sam/dm-core/tr... and make the above tweak to SVN DM on Rubyforge.
Thanks, -Sam
-
Sam Smoot May 8th, 2008 @ 04:43 PM
- Assigned user changed from Scott Bauer to Adam French
Adam, please apply (to 0.3.x SVN) and close this out.
-
Sam Smoot May 20th, 2008 @ 08:34 PM
Adam, didn't you take care of this already? Can we close it out?
-
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »