Best Way To Manage Mutable Public Rails Return Types
38 views
Skip to first unread message
Matt Glover
unread,
Feb 24, 2014, 10:47:30 PM2/24/14
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to rubyonra...@googlegroups.com
Our team ran
into a problem in a Rails application today where someone unknowingly
modified Rails internals leading to bad query generation. The developer modified the list of attribute names for a model by reading and then mutating the contents of attribute_names on an ActiveRecord model class. For a variety of reasons it was not immediately obvious that they were modifying the results of this call so it took a while to track down.
Certain query generation code paths, such as distinct counts, can rely on private methods like aggregate_column that depend on an accurate list of column names to properly prefix column names with table names. Because attribute_names happens to expose the internal array used to track column names any modifications to the return value of attribute_names can break query generation.
In our case developers did not intend to modify a core array utilized by Rails for query generation when they modified the results of the public-facing method. On the other hand I imagine there are cases where this level of mutability in Ruby and Rails is helpful to people writing plugins. My core question is how others recommend my team avoid this particular class of issue going forward.
A few possibilities immediately come to mind:
Someone much smarter than me comes up with a better solution than anything that follows
Via thorough testing, static analysis, code review, and careful attention try to avoid this class of issue going forward
Interested in any tools or other advice to aid this effort
Find documentation that identifies the publicly visible Rails methods intended to be part of the public API
Perhaps some documentation considers methods like attribute_namesthat can trigger this type of issue to be excluded from the Rails API
Is there a clear line between publicly visible Rails methods and intended parts of the API?
Claim this behavior is a bug and submit a patch for it because mutation of the resulting array has problematic implications and it arguably breaks encapsulation
I do not plan to pursue this approach unless there is broad agreement that the current behavior is incorrect as mutability is commonplace in Ruby
For the sake of this post I am interested in this particular method call but not interested in a theoretical discussion about mutability and encapsulation in general
I am happy to have a separate theoretical discussion on those broader topics via a channel that does not spam the entire mailing list