From aff7bd7e2a76af306ece36b05e0d5244f0c174c0 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Sun, 1 Dec 2013 17:30:31 -0500 Subject: [PATCH] Make `order` option Rails 4.0.1-compatible The way that we figure out whether the value which is passed to `order` is the same as the `order` that the association was defined with is by creating an ActiveRecord::Relation object from the given `order` and comparing it with the Relation stored under the association. Specifically, every time you call `order` on a Relation, it appends the value you've given to an internal `order_values` array, so we actually access this array and compare the two between the two Relation objects. Currently we assume that this `order_values` array is an array of strings, so it's very easy to compare. That was valid pre-Rails 4.0.1, but it looks like as per [these][1] [commits][2], it's now possible for `order_values` to be an array of Arel nodes. So, to make a proper comparison, we have to convert any Arel nodes to strings by calling #to_sql on them. [1]: https://github.com/rails/rails/commit/d345ed4 [2]: https://github.com/rails/rails/commit/f83c9b10b4c92b0d8deacb30d6fdfa2b1252d6dd --- .../association_matchers/model_reflector.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb b/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb index a8a9cac0..0c44f2f9 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb @@ -37,15 +37,26 @@ module Shoulda # :nodoc: def extract_relation_clause_from(relation, name) case name - when :conditions then relation.where_values_hash - when :order then relation.order_values.join(', ') - else raise ArgumentError, "Unknown clause '#{name}'" + when :conditions + relation.where_values_hash + when :order + relation.order_values.map { |value| value_as_sql(value) }.join(', ') + else + raise ArgumentError, "Unknown clause '#{name}'" end end private attr_reader :subject, :name + + def value_as_sql(value) + if value.respond_to?(:to_sql) + value.to_sql + else + value + end + end end end end