# CreativeRailsUtilities Defines extensions, useful and convenient methods on Ruby and Rails base classes. Requires `Ruby >=2.1` for keyword arguments. Intended for `Rails >= 4.0.0`, but will probably work for older projects with robust Activesupport inclusion. ## Installation `gem 'creative_rails_utilities', "~> 0.3.3"` and `bundle` ## Usage Feel free to read the source under `/lib/creative_rails_utilities/` and peruse the method "it" lines under `/spec` #### View Helpers Rails-only (via railtie) view helpers have been added, they are automagically loaded and usable upon gem inclusion. ##### relative_time_parse(earlier_time, later_time=optional) turns a timestamp into "time ago" format. Examples: ```ruby # If used with only one argument, will default the second argument to Time.now # at "2015-01-15 12:00".to_datetime relative_time_parse("2015-01-15 12:00".to_datetime) #=> {key: "now", count: nil} relative_time_parse("2015-01-15 11:59:59".to_datetime) #=> {key: "second", count: nil} relative_time_parse("2015-01-15 11:59:58".to_datetime) #=> {key: "seconds", count: "1"} relative_time_parse("2015-01-15 11:59:00".to_datetime) #=> {key: "minute", count: nil} relative_time_parse("2015-01-15 11:58:00".to_datetime) #=> {key: "minutes", count: "2"} relative_time_parse("2015-01-15 11:00".to_datetime) #=> {key: "hour", count: nil} relative_time_parse("2015-01-15 09:00".to_datetime) #=> {key: "hours", count: "3"} relative_time_parse("2015-01-14 11:00".to_datetime) #=> {key: "day", count: nil} relative_time_parse("2015-01-10 09:00".to_datetime) #=> {key: "days", count: 5} # if used with both arguments, expects the second to be later than the first and will calculate relative time between them relative_time_parse("2015-01-01 12:00".to_datetime, "2015-01-01 12:02".to_datetime) #=> {key: "minutes", count: "2"} ``` The keys are intended to be used together with `I18n.t` Sample yaml for English ```yml en: time: now: "just now" second: "a second ago" seconds: "%{count} seconds ago" minute: "a minute ago" minutes: "%{count} minutes ago" hour: "an hour ago" hours: "%{count} hours ago" day: "a day ago" days: "%{count} days ago" ``` Then you can write a simple helper that specifies localization key location and returns the correct value based on the hash returned by `relative_time_parse` ```ruby def relative_short_time(t1, t2=nil) hash = relative_time_parse(t1, t2) count_hash = hash.count.present? ? hash.except(:key): {} return I18n.t("time.#{hash[:key]}", count_hash) end ``` ##### Date ```ruby # get an array of date objects Date.build_date_array("2015-10-11", "2015-10-13") #=> ["2015-10-11".to_date, "2015-10-12".to_date "2015-10-13".to_date] ``` ```ruby # get an array of dates between one date object and another "2015-10-11".to_date.build_date_array("2015-10-09") #=> ["2015-10-09".to_date, "2015-10-10".to_date, "2015-10-11".to_date] ``` ```ruby # build a range of dates that will never go beyond a limit and/or yesterday # used for accessing pre-churned data for strictly past days # Called on "2015-10-13" "2015-10-11".to_date.array_with_pre_churn_limit(30) #=> ["2015-10-11".to_date, "2015-10-12".to_date] # Called on "2015-12-25" "2015-10-11".to_date.array_with_pre_churn_limit(30) #=> ["2015-10-11".to_date, .. 28 .. , "2015-11-10".to_date ] ``` ##### Hash ```ruby # build a hash from variables and methods, more at https://github.com/Epigene/hashrush key1 = "a" def key2; return "b"; end Hash.rush(binding, :key1, :key2) #=> {key1: "a", key2: "b"} ``` ```ruby # fast sort by key some_hash.fast_sort_keys #=> some_sorted_hash ``` ```ruby # ensure a hash has a range of integer keys (useful for graphs) {}.populate_with_keys(min: 1, max: 3) #=> {1 => 0, 2 => 0, 3 => 0} ``` ##### Numeric ```ruby # integer into letters 1.to_s26 #=> "a" 28.to_s26 #=> "ab" ``` ```ruby # get a part even when deleting with zero # whole.safe_part(part) 100.safe_part(50) #=> 0.5 1.safe_part(2) #=> 2 0.safe_part(0) #=> 0 ``` ```ruby # get a percent even when deleting with zero # whole.safe_percent(part) 100.safe_percent(50) #=> 50 1.safe_percent(2) #=> 200 3.0.safe_percent(1) #=> 33.333333333333336 # you should .round when calling this on floats 0.safe_percent(0) #=> 0 ``` ```ruby # transform a Numeric that denotes seconds into a hash of how many :days, :hours, :minutes ad :seconds that is 61.5.to_time_hash #=> {days: 0, hours: 0, minutes: 1, seconds: 1.5} 2775721.to_time_hash #=> {days: 32, hours: 3, minutes: 2, seconds: 1} (Time.zone.now.to_i - 3.minutes.ago.to_i).to_time_hash #=> {days: 0, hours: 0, minutes: 3, seconds: 0} ``` ##### String ```ruby # letters into integer "z".to_i26 #=> 26 "apple".to_i26 #=> 749325 ``` ```ruby # removes leading, trailing and repeated middle whitespace " z z ".clean_whitespace #=> "z z" ``` ```ruby # Unindent here doc type strings to the indentation level of first line string = <<-ENDBAR.unindent 1 2 3 1 ENDBAR string #=> "1..." instead of " 1..." ``` ```ruby # Convert string to boolean. "true".to_bool #=> true "faLSE".to_bool #=> false # yup, case insensitive "0".to_bool #=> false "".to_bool #=> false "y".to_bool #=> true ``` ## Development Use ruby >=2.1 1. Write specs 2. Make specs fail 3. Write feature 4. Make tests pass 5. Update README.md with examples 6. Update CHANGELOG.md with changes/fixes/additions. 7. Bump version and `rake release` ## Contributing Bug reports and pull requests are welcome on [GitHub](https://github.com/CreativePublisher/rails_utilities) ## License The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).