Ticket #41 (new defect)

Opened 9 months ago

Passing in options to reload is not always supported

Reported by: rails Assigned to: jcm
Priority: major Milestone:
Component: doc Version:
Keywords: Cc:

Description

The last stable release of better_nested_set calls the reload method without any options. Currently in trunk, an optimization has been made to pass in options to only select the left, right and parent_id fields when reloading. For example in the move_to method you have code that looks like:

self.reload (:select => "#{left_col_name}, #{right_col_name}, #{parent_col_name}") # the lft/rgt values could be stale (target is reloaded below)
if target.is_a?(base_set_class)
  target.reload (:select => "#{left_col_name}, #{right_col_name}, #{parent_col_name}") # could be stale
else
  target = self.class.find_in_nested_set(target) # load object if we were given an ID
end 

A problem exists because of passing in options to the calls to reload. ActiveRecord::Base#reload takes the options, but AssociationProxy? defines its own reload method which *does not* take in any options.

Also, there is a oversight in Rails (has existed forever) in AssociationProxy?. The oversight is that they currently keep "send" on the AssociationProxy?, but remove "send!". This means that calls to "send!" are forwarded onto the proxy target, and calls to "send" are kept on the proxy. This is an annoying issue because the following will work:

target.send! :reload, :select => "foo, bar, baz"

while the following will fail:

target.send :reload, :select => "foo, bar, baz" # throws an ArgumentError, wrong number of arguments (1 for 0) 

At this time I would recommend removing the optimization or surrounding the optimization in begin/rescue blocks so it will fallback to reloading without the optimization if an ArgumentError? is thrown.

If any questions let me know,

Zach Dennis zach.dennis at gmail dot com http://www.continuousthinking.com