ActiveRecord crashes with YAML for Ruby 1.8.4
back
ActiveRecord objects can be serialised, and this should not be a surprise. With the native YAML format, any Ruby object can be turned into a human readable text string, which in turn can be converted back into the original object. In the process of trying to serialise my ActiveRecord objects into a YAML string for storage in a file, I encountered this small problem when I tried to convert the string back to the original object, in that ActiveRecord throws an exception:
You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occured while evaluating nil.include? /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/base.rb:1402:in `respond_to?' /usr/lib/ruby/1.8/yaml.rb:133:in `load' /usr/lib/ruby/1.8/yaml.rb:144:in `load_file' /usr/lib/ruby/1.8/yaml.rb:143:in `load_file'
After searching for this problem on Google, I found this posting which shows the problem is in the file activerecord/lib/base.rb itself, on line 1402, as shown in the stack trace above. I would just like to elaborate a bit that this problem exists in the most current version of ActiveRecord library, namely version 1.13.2, and Ruby, of version 1.8.4. This problem obviously should be patched in a future version of Rails. As the author of the above posting suggests, the original code around line 1402, which looks like:
def respond_to?(method, include_priv = false) if attr_name = self.class.column_methods_hash[method.to_sym] return true if @attributes.include?(attr_name) || attr_name == self.class.primary_key return false if self.class.read_methods.include?(attr_name) elsif @attributes.include?(method_name = method.to_s)
should be changed to
def respond_to?(method, include_priv = false) if @attributes.nil? return super elsif attr_name = self.class.column_methods_hash[method.to_sym] return true if @attributes.include?(attr_name) || attr_name == self.class.primary_key return false if self.class.read_methods.include?(attr_name) elsif @attributes.include?(method_name = method.to_s)
Hope it helps someone else if they try to do the same thing.
back
|