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 = {})
This commit is contained in:
Lauro Caetano 2013-12-11 00:05:16 -02:00
parent 11c0ef58a6
commit 23ce3e5fde
3 changed files with 16 additions and 2 deletions

@ -84,13 +84,18 @@ def result
"#{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

@ -12,6 +12,7 @@
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 @@ def test_find_by_one_attribute_bang
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!")

@ -245,6 +245,7 @@ def create_table(*args, &block)
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|