-
Notifications
You must be signed in to change notification settings - Fork 21.9k
Moving number helper from ActionView to Active Support #6315
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
Moving number helper from ActionView to Active Support #6315
Conversation
hey @amutz, this pull request cannot be automatically merged. Please rebase it against the master |
Hi @rafaelfranca, I've rebased this against master. Did that fix the problem? Thanks, |
Yep, it's totally merge-able now. |
str << "+#{country_code}#{delimiter}" unless country_code.blank? | ||
str << number | ||
str << " x #{extension}" unless extension.blank? | ||
ERB::Util.html_escape(str) |
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 is not a responsibility of Numeric, should probably be in the Action View only.
Great job! I really like this. I have added some comments regarding the code, and besides that, two small things:
|
|
||
private | ||
|
||
def self.format_translations(namespace, locale) |
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.
Notice that since those are class methods, they are not really being private here. You need to wrap them inside a class << self block.
class Foo
private
def self.gotcha!
1
end
end
Foo.gotcha! #=> 1
👍 It was weird to have |
+1 to the pull request. +1 to removing every aspect of |
end | ||
|
||
|
||
|
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.
Whitespaces ✂️
👍 great |
👍 to all the remarks of @josevalim, would favor To be complete, this pull request should also update the AS guide. I need to double-check if the presence of a locale in this code is fine, not sure we can count on a locale for core extensions since people should be able to cherry-pick just one file (see the top of the AS guide), and that should work outside Ruby on Rails. |
@fxn just as a side note, I have an open pull request to add defaults to all these number helpers, but I was using I18n as defaults. After talking to @josevalim we decided that it's better to have these defaults as constants, so I have to update the pull request, but now I think I should wait for this change. |
Ok, great. I'll make the changes mentioned by @josevalim to keep certain concerns in NumberHelper, I'll rename the instance methods to to_s, and I'll fix the method protection of the class method. And I will update the AS guide, per the request by @fxn. Regarding a way to avoid having class versions of each, I'm open to suggestions. In order to support things like "number_to_currency('123a456') => $123a456" (which there are explicit tests for), we need to be able to have methods that operate on strings (as @josevalim correctly pointed out). I considered having only instance methods and having an option that could be passed to include a string (like 0.to_currency(:number => "123a456") => $123a456), but that seemed uglier than class methods. Any suggestions here are welcome. I'll update the pull request with the changes in a day or two. Thanks for all the feedback! |
The ActionView methods may need to retain their interface, but the new ActiveSupport methods do not. The ActiveSupport methods, especially the core-ext methods, can change the interface. For example, the |
Agreed with @yfeldblum, in Action View you need to be string-friendly, but in core extensions you implement the natural interface only. |
@fxn @yfeldblum the problem is that you may lose information in the process, like converting this phone number "043 321 932" to an integer and then back to a phone number. |
@josevalim
|
Thanks for the ideas. @yfeldblum that solution works, but it feels unnatural to me to put the implementation of what are NumberHelper methods injected to all strings. Yes, we want to support translating a string that is numberish into a phone number, but for most strings these methods wont be relevant. It would surprise me if I looked at the methods for "banana" and found a "to_phone" method. |
They don't have to be methods on String or Number necessarily. But they should be in ActiveSupport not ActionView. The phone-related methods should take strings, and convert numbers to strings, while other methods should take numbers, and convert strings to numbers. |
How about a class P.S. Maybe even better: P.P.S. BTW, as functions in Ruby are written right-to-left, i prefer Update 2012-05-18. Here is what i am thinking about: french = Locale.new(:fr)
ten_euros_in_french = french.currency_from_number(10) |
Thanks for all the feedback! I've made the following improvements: I've moved the output safety concerns back to NumberHelper, fixed the class method protection and updated the ActiveSupport guide. The methods now are versions of to_s: 1235551234.to_s(:phone) # => 123-555-1234
1234567890.50.to_s(:currency) # => $1,234,567,890.50
100.to_s(:percentage) # => 100.000%
12345678.to_s(:delimited) # => 12,345,678
111.2345.to_s(:rounded) # => 111.235
123.to_s(:human_size) # => 123 Bytes
1234567890123456.to_s(:human) # => "1.23 Quadrillion" The class versions are still around, because I could not find a good way to get rid of them. I have changed the names of the "with_" methods, to have more consistency: Numeric.to_phone(5551234) # => 555-1234
Numeric.to_currency(1234567890.50) # => $1,234,567,890.50
Numeric.to_percentage(100) # => 100.000%
Numeric.to_delimited(12345678) # => 12,345,678
Numeric.to_rounded(111.2345) # => 111.235
Numeric.to_human_size(123) # => 123 Bytes
Numeric.to_human(123) # => "123" Regarding the I18n concerns, I've added the AS en.yml file to the I18n load_path when it's not already there. As a result, you can load just formatting.rb alone and it should function properly. Thanks again for all the feedback! Let me know if there's any more changes desired and I can make them. |
klass.send(:alias_method, :to_s_without_formatting, :to_s) | ||
|
||
klass.send(:define_method, :to_s) do |*args| | ||
if args.size > 0 && args[0].is_a?(Symbol) |
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.
Don't need to check for the size. args[0].is_a? Symbol
is enough.
I don't think the I18n path munging is required at all. It is a small change and since it is Rails 4, it is fine to change the contents of .yml files. We just need to mention it in the CHANGELOG. |
Ok great thanks. I've removed the unnecessary check of the args.size. Regarding removing the i18n load_path file stuff, just to be clear, this will mean that if you cherry pick this single file from ActiveSupport and load it alone, these methods won't work properly. According to @fxn, people should be able to load a single file in AS and have it work. Let me know what you'd like me to do with the i18n stuff, and if the methods should be named to_formatted_s instead. Thanks again for all the feedback! |
Then can't you simply require "active_support/i18n" at the top instead? |
Ok, I misunderstood what you were saying. You are correct. I've updated the code. Thanks! |
Based on @josevalim's comments, I would still suggest moving the implementation of I'm also not necessarily sure I would stick the formatting methods on |
@yfeldblum, in my opinion, methods that format numbers and numberish strings make more sense on Numeric than on String. Having them sit in a separate module works, but feels about as clean as having them be class methods, to me. If the community as a whole feels that I should move these class methods to a separate, ActiveSupport-specific module, I can do that. Is there anything more I can do to move this forward? Are we waiting on @fxn 's input on whether the methods should be to_s or to_formatted_s? Let me know if there's any way I can help. Thanks. |
I am for keeping formatting methods in a separate module |
Yes, The blank lines between RDoc and method definitions should be removed, and we would need a CHANGELOG entry in Active Support. @josevalim other than that the patch is OK for you? |
@fxn should we still monkey patch Also, since we are monkey patching
Nonetheless @amutz, thanks for your work. I am aware that you have already changed things many times, but those changes are big and not so trivial to take. |
Absolutely, I don't mind changing things, it's my pleasure to help. I'll move the methods from being injected on the Numeric class, to a module. I may open a separate pull request because there have been a lot of changes and rebasing started to get weird on me and I'm not exactly a git ninja. I will make the changes in a few days. Regarding monkeypatching
(as a side note, perhaps conversions.rb is a more appropriate for the file than formatting.rb, given that to_formatted_s lives in conversions.rb for other core_ext code) |
OK. So let's move the class methods to a module that extends itself and feel free to rename the file to conversions. Please rebase everything and let's merge it! :D |
Ok, I've made the desired changes and squashed and rebased them into a single commit. Per @josevalim 's request, the methods now reside in Let me know if you'd like any other changes. Thanks for all the feedback! |
…o_active_support Moving number helper from ActionView to Active Support
Beautiful, thanks! |
That’s because `number_to_rounded` was only added in rails/rails#6315
That’s because `number_to_rounded` was only added in rails/rails#6315
Hi,
In an earlier pull request I hoped we could decouple ActiveSupport from ActionView:
#5675
It was suggested by @josevalim that instead of that approach, we move the number helpers from ActionView to ActiveSupport. In addition to his suggestion, this approach was a feature request in a separate issue:
#3214
In this pull request I've moved the functionality from NumberHelper in ActionView to ActiveSupport and added the methods to Numeric. So instead of including NumberHelper and writing "number_to_human(123)", you could just include ActiveSupport and write "123.to_human". The original NumberHelper methods are all left in place and accept the same options and behave the same (and just pass through to the AS implementation in Numeric).
Other interested parties may include: @carlosantoniodasilva, @fxn, and @yfeldblum.
Let me know if you'd like any changes to this implementation.
Thanks,
Andrew.