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 also work for older projects with robust Activesupport inclusion.
Installation
gem 'creative_rails_utilities' 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:
# 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
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
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
# 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]
# 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]
# 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
# 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"}
# fast sort by key
some_hash.fast_sort_keys #=> some_sorted_hash
# 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
# integer into letters
1.to_s26 #=> "a"
28.to_s26 #=> "ab"
# 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
# get a percent even when deleting with zero
# whole.safe_percent(part)
100.safe_percent(50) #=> 50
1.safe_percent(2) #=> 200
0.safe_percent(0) #=> 0
String
# letters into integer
"z".to_i26 #=> 26
"apple".to_i26 #=> 749325
# removes leading, trailing and repeated middle whitespace
" z z ".clean_whitespace #=> "z z"
# 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..."
Development
Use ruby >=2.1
- Write specs
- Make specs fail
- Write feature
- Make tests pass
- Update README.md with examples
- Update CHANGELOG.md with changes/fixes/additions.
- Bump version and
rake release
Contributing
Bug reports and pull requests are welcome on GitHub
License
The gem is available as open source under the terms of the MIT License.