Created
June 13, 2015 00:36
-
-
Save JayTeeSF/0af43b8b6312b4195e89 to your computer and use it in GitHub Desktop.
Calling new on an AR class, from within the context of an ActiveRelation on a subclass of said class, assumes the "id" attribute defined in the relation's where clause
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
class ArWeirdnessUsage | |
def self.run | |
message = <<-EOF | |
Usage: | |
0) make this file executable and run it in order to see these instructions | |
1) Create a Rails Project (rails new foo) and add this file: cp %s ./foo/lib/ | |
2) rails g scaffold TestClass name && RAILS_ENV=test rake db:create db:migrate | |
3) echo 'TestClass; ArWeirdness.test_suite' \\ | |
| rails c --environment=test | |
4) Cleanup: | |
echo 'ActiveRecord::Base.connection.execute("drop table test_classes")' \\ | |
| rails c --environment=test && rails destroy scaffold TestClass | |
You may also want to remove stray files like: | |
db/schema.rb | |
app/assets/stylesheets/scaffolds.scss | |
with either 'git checkout ...' or 'rm ...' | |
EOF | |
return(message % $PROGRAM_NAME) | |
end | |
end | |
if __FILE__ == $PROGRAM_NAME | |
puts ArWeirdnessUsage.run | |
else | |
class ArWeirdness | |
COMMON_ATTRS = { } # <-- put any required attributes here; sorry, can't handle attributes that must be unique. | |
def self.test_setup | |
::TestClass.create!(COMMON_ATTRS.merge(name: 'foo')) | |
::TestClass.create!(COMMON_ATTRS.merge(name: 'bar')) | |
end | |
def self.test_cleanup | |
::TestClass.delete_all | |
end | |
module ExtraFunctionality | |
def create_instance_of_test_class(attrs={}) | |
ret_val = BROKEN_TEST | |
new_record = ::TestClass.new(attrs) # this new record shouldn't have an ID! | |
if new_record.id.present? | |
ret_val = BUG | |
puts " ------------> huh: generated a new instance with an ID assigned?!" # the id of the activerecord relation got in our way! | |
else | |
ret_val = BUG_FREE | |
puts " ------------> ok" | |
end | |
puts "\tWe have #{new_record.inspect}" | |
puts "\tfrom: #{attrs.inspect}" | |
return ret_val | |
end | |
end | |
class SubsetOfTestClass < ::TestClass | |
extend ExtraFunctionality | |
end | |
def self.test_suite | |
test_ok | |
test_huh | |
end | |
BUG = -1; BROKEN_TEST = 0; BUG_FREE = 1 | |
def self.test_ok # this WORKS ...it creates a new object without picking-up the "id" of the collection | |
test_setup | |
ids = ::TestClass.pluck(:id) | |
@id = ids.first | |
@filtered_collection = ::TestClass.where(id: [@id]) #<-- the use-case: to present a filtered_version of TestClass with only the current user's entries | |
@filtered_collection.send(:extend, ExtraFunctionality) | |
result = @filtered_collection.create_instance_of_test_class(COMMON_ATTRS.merge(name: 'foo-bar-baz-OK')) | |
test_cleanup | |
return result | |
end | |
def self.test_huh # this FAILS ...it creates a new object, that ?magically? picks-up the id of the ARRelation within which it's defined | |
test_setup | |
ids = ::TestClass.pluck(:id) | |
@id = ids.first | |
@filtered_collection = SubsetOfTestClass.where(id: [@id]) #<-- the use-case: to present a filtered_version of TestClass with only the current user's entries | |
result = @filtered_collection.create_instance_of_test_class(COMMON_ATTRS.merge(name: 'foo-bar-baz-HUH')) | |
test_cleanup | |
return result | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment