-
Notifications
You must be signed in to change notification settings - Fork 179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pluck change from array access to using methods. #299
pluck change from array access to using methods. #299
Conversation
c447ce6
to
66c5234
Compare
(CI failed)It looks like Rails 7.1.3 breaks polymorphic associations ... 🤔 |
@iberianpig see #300 for the Rails 7.1.3 fix |
kicking now that 300 was merged |
looking like the tests introduced by 299 are still passing. |
- execute method of symbol name specified by pluck for record - Until v3.1.1, it was a specification to execute the method of the symbol name, so the same result is obtained.
66c5234
to
8ea4256
Compare
@kbrock Please confirm Reproduce section in this issue. You can reproduce this issue in your terminal.
I rebased and pushed this branch, then All checks in CI have all passed. 1) Failure:
BugTest#test_pluck_with_enumerize [issue.rb:44]:
--- expected
+++ actual
@@ -1 +1 @@
-[["US", "north_america"], ["Canada", "north_america"]]
+[["US", 1], ["Canada", 1]]
1 runs, 2 assertions, 1 failures, 0 errors, 0 skips |
@iberianpig Sorry, I was not clear. Let me try again. Good job. The tests introduced by #269 are still passing. Request: Is there a way to introduce a test (that does not rely upon |
Thank you for your feedback. |
lib/active_hash/relation.rb
Outdated
symbolized_column_names.map { |column_name| record[column_name] } | ||
end | ||
# `tap with break` can be replaced with yield_self in Ruby 2.5 or then in Ruby 2.6 | ||
column_names.map { |column_name| all.map(&column_name.to_sym) }.tap { |values| break :zip.to_proc.(*values) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the bug you highlighted is we do not want to call record[column_name]
but rather record.public_send(column_name)
. (or send
?)
Think this bug is based around active record overriding array accessor and calling the public method behind the scenes. We use the actual array method. So using the array accessor will not pick up the public attribute method override.
This code has gone through at least 3 iterations:
# first
column_names.map { |column_name| all.map(&column_name.to_sym) }.inject(&:zip)
#269
all.map do |record|
symbolized_column_names.map { |column_name| record[column_name] }
end
#299
column_names.map { |column_name| all.map(&column_name.to_sym) }.then { :zip.to_proc.(*_1) }
I'm finding the zip
and the tap
/then
a little complicated to mentally parse. (both versions of the zip code). Not sure what the extra traversals buy us.
Does something like this work for you?
(does send/public_send fix your bug?)
all.map { |record| column_names.map { |column_name| record.public_send(column_name) } }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the zip buys us some performance or something? Please share. Though, the non-zip version seems to be simpler for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your great feedback.
I initially implemented pluck in a way that was closer to the original code.
However considering your feedback, proceeding as you've recommended seems better, especially from a performance standpoint.
Here are the results of the benchmark script:
Benchmark.bm 25 do |r|
r.report "pluck(first)" do
100000.times { CountryWithContinent.pluck_with_first(:id, :name, :continent) }
end
r.report "pluck(#269)" do
100000.times { CountryWithContinent.pluck_with_269(:id, :name, :continent) }
end
r.report "pluck(#299)" do
100000.times { CountryWithContinent.pluck_with_299(:id, :name, :continent) }
end
r.report "pluck(public_send)" do
100000.times { CountryWithContinent.pluck(:id, :name, :continent) }
end
end
user system total real
pluck(first) 2.655054 0.001351 2.656405 ( 2.656560)
pluck(#269) 0.919349 0.000053 0.919402 ( 0.919459)
pluck(#299) 1.843044 0.004067 1.847111 ( 1.847146)
pluck(public_send) 0.853149 0.000000 0.853149 ( 0.863946)
I'll move forward with the public_send approach. This seems like a step in the right direction. Thanks for your suggestion 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh wow. thanks.
Yes, you were definitely following the original code's style. I appreciate that.
After looking at the numbers, I don't feel so bad wanting to go with what I consider a simpler style.
33f0960
to
d14f25e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great.
Since the pre 269 code uses the method access, this looks like it shouldn't introduce any unintended side effects
@kbrock When is the release likely to include the contents of this pull request? 😄 |
- Support `has_many :through` associations active-hash#296 @flavorjones - Rails 7.1 support active-hash#291 @y-yagi - Rails 7.1: fix sqlite3 issue active-hash#303 @flavorjones - Rails 7.1.3: add missing `has_query_constraints?` active-hash#300 @flavorjones - `Array#pluck` supports methods active-hash#299 @iberianpig - Prefer `safe_constantize` over `constantize` active-hash#297 @flavorjones - Treat `nil` and `blank?` as different values active-hash#295 @kbrock - Fix `#where` for string keys active-hash#292 @usernam3
- Ruby 3.3 support active-hash#298 @m-nakamura145 - Support `has_many :through` associations active-hash#296 @flavorjones - Rails 7.1 support active-hash#291 @y-yagi - Rails 7.1: fix sqlite3 issue active-hash#303 @flavorjones - Rails 7.1.3: add missing `has_query_constraints?` active-hash#300 @flavorjones - `Array#pluck` supports methods active-hash#299 @iberianpig - Prefer `safe_constantize` over `constantize` active-hash#297 @flavorjones - Treat `nil` and `blank?` as different values active-hash#295 @kbrock - Fix `#where` for string keys active-hash#292 @usernam3
Restore ActiveHash::Relation#pluck to execute the specified method on the record.
Background:
attributes[key]
, affecting compatibility.#269 broke functionality of gems like
enumerize
which rely on casting values accessed by column names.Reproduce
gem "active_hash", "3.2.1" # fail test
.$ ruby issue.rb
3.1.1
3.2.1