aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLauro Caetano <laurocaetano1@gmail.com>2013-12-11 00:05:16 -0200
committerLauro Caetano <laurocaetano1@gmail.com>2013-12-11 01:00:32 -0200
commit23ce3e5fde42d0af9b77ad014bde8f36401fa3b6 (patch)
tree20d6a3b33ffe2d6d50df8bd80e1562abbc13d850
parent11c0ef58a6cd278fc6b5d81a7724d9bcdb47f623 (diff)
downloadrails-23ce3e5fde42d0af9b77ad014bde8f36401fa3b6.tar.gz
rails-23ce3e5fde42d0af9b77ad014bde8f36401fa3b6.tar.bz2
rails-23ce3e5fde42d0af9b77ad014bde8f36401fa3b6.zip
Prevent invalid code when using dynamic finders with Ruby's reserved words.
The dynamic finder was creating the method signature with the parameters name, which may have reserved words and this way creating invalid Ruby code. Closes: #13261 Example: # Before Dog.find_by_alias('dog name') # Was creating this method def self.find_by_alias(alias, options = {}) # After Dog.find_by_alias('dog name') # Will create this method def self.find_by_alias(_alias, options = {})
-rw-r--r--activerecord/lib/active_record/dynamic_matchers.rb9
-rw-r--r--activerecord/test/cases/finder_test.rb8
-rw-r--r--activerecord/test/schema/schema.rb1
3 files changed, 16 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/dynamic_matchers.rb b/activerecord/lib/active_record/dynamic_matchers.rb
index e650ebcf64..5caab09038 100644
--- a/activerecord/lib/active_record/dynamic_matchers.rb
+++ b/activerecord/lib/active_record/dynamic_matchers.rb
@@ -84,13 +84,18 @@ module ActiveRecord
"#{finder}(#{attributes_hash})"
end
+ # The parameters in the signature may have reserved Ruby words, in order
+ # to prevent errors, we start each param name with `_`.
+ #
# Extended in activerecord-deprecated_finders
def signature
- attribute_names.join(', ')
+ attribute_names.map { |name| "_#{name}" }.join(', ')
end
+ # Given that the parameters starts with `_`, the finder needs to use the
+ # same parameter name.
def attributes_hash
- "{" + attribute_names.map { |name| ":#{name} => #{name}" }.join(',') + "}"
+ "{" + attribute_names.map { |name| ":#{name} => _#{name}" }.join(',') + "}"
end
def finder
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 5e8f1c851f..7a00f7fa8f 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -12,6 +12,7 @@ require 'models/developer'
require 'models/customer'
require 'models/toy'
require 'models/matey'
+require 'models/dog'
class FinderTest < ActiveRecord::TestCase
fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations
@@ -641,6 +642,13 @@ class FinderTest < ActiveRecord::TestCase
assert_raise(ActiveRecord::RecordNotFound) { Topic.find_by_title!("The First Topic!") }
end
+ def test_find_by_on_attribute_that_is_a_reserved_word
+ dog_alias = 'Dog'
+ dog = Dog.create(alias: dog_alias)
+
+ assert_equal dog, Dog.find_by_alias(dog_alias)
+ end
+
def test_find_by_one_attribute_that_is_an_alias
assert_equal topics(:first), Topic.find_by_heading("The First Topic")
assert_nil Topic.find_by_heading("The First Topic!")
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 92e2e4d409..ac546fc296 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -245,6 +245,7 @@ ActiveRecord::Schema.define do
t.integer :trainer_id
t.integer :breeder_id
t.integer :dog_lover_id
+ t.string :alias
end
create_table :edges, force: true, id: false do |t|