# EitilCore EitilCore extends the core classes of Ruby and Rails. ## ApplicationController ```ruby require "eitil_core/active_record" ``` ```ruby # require "eitil_core/active_record/array_to_relation" [].to_relation(fallback_class = ApplicationRecord) # converts an array of ActiveRecord instances to an ActiveRecord_Relation instance # call as: [#,].to_relation # if the object is an empty array, the intended class cannot be derived from the object, so in order to # prevent NoMethodError's you can optionally pass a fallback class which will be used to create an empty association ``` ## ApplicationController ```ruby require "eitil_core/application_controller" require "eitil_core/application_controller/permit_model_atts" ``` ```ruby # require "eitil_core/application_controller/slice_params" slice_params(*args) # slices request params, converts them to JSON and symbolizes the keys # call as: slice_params :id, :user # => { id: 1, user: 69 } permit_model_atts(*models, include: nil, except: nil) # calls params.permit and automatically permits the columns of all given models (one or more) # also accepts additional permits (include: nil) or allows you to reject column values (except: nil) # call as: params.permit_model_atts(BillingInfo, BillingIntegration, except: :credit_card) ``` ## ApplicationRecord ```ruby require "eitil_core/application_controller" ``` ```ruby # require "eitil_core/application_record/duck_find" self.duck_find(identifier) # tries to find a record for the model through a wide accepting parameter, which may either be: # 1) an instance of the model, 2) an Integer, 3) a Float or 4) a stringified number # call as: User.duck_find("11") ``` ```ruby # require "eitil_core/application_record/find_by_like" self.find_by_like(_hash) # runs .find_by with your string field made into a wildcard and case insensitive # call as: User.find_by_like(name: 'jurriaan') ``` ```ruby # require "eitil_core/application_record/where_like" self.where_like(_hash) # runs .where with your string field made into a wildcard and case insensitive # call as: User.where_like(name: 'jurriaan') ``` ```ruby # require "eitil_core/application_record/all_associations" self.all_associations # returns all associations for a given model # call as: Environment.all_associations ``` ## ArgumentHelpers ```ruby require "eitil_core/arugment_helpers" ``` ```ruby # require "eitil_core/argument_helpers/all_args_to_ivars" all_args_to_ivars(binding) # sets all keywords arguments of the method's local binding to instance variables # call as: all_args_to_ivars binding ``` ```ruby # require "eitil_core/argument_helpers/all_args_to_ivars_bang" all_args_to_ivars! # works the same as .all_args_to_ivars, except that passing the binding is no longer required # production usage is discouraged by the creator of the supporting gem ``` ```ruby # require "eitil_core/argument_helpers/all_kwargs_to_ivars" all_kwargs_to_ivars(local_binding, namespace= :kwargs) # sets the method's **kwargs argument to instance variables, with each key as the ivar's "@#{name}" and the value as its value # call as: kwargs_to_ivars binding # the keywords container name can be overwritten, e.g. the common :attributes ``` ```ruby # require "eitil_core/argument_helpers/all_kwargs_to_ivars_bang" all_kwargs_to_ivars!(namespace= :kwargs) # works the same as .all_kwargs_to_ivars, except that passing the binding is no longer required # production usage is discouraged by the creator of the supporting gem ``` ```ruby # require "eitil_core/argument_helpers/args_to_h" args_to_h(binding, *local_vars) # creates a hash, with a given local_var as keys and its value as value # call as: args_to_h(binding, :username, :password) # => { username: 'jurriaan', password: 'matz_is_nice' } ``` ```ruby # require "eitil_core/argument_helpers/args_to_h_bang" args_to_h!(*local_vars) # works the same as .args_to_h, except that passing the binding is no longer required # production usage is discouraged by the creator of the supporting gem ``` ```ruby # require "eitil_core/argument_helpers/args_to_ivars" args_to_ivars(binding, *local_vars) # sets specified keywords arguments of the method's local binding to instance variables # call as: all_args_to_ivars binding :user_id, :user_name ``` ```ruby # require "eitil_core/argument_helpers/args_to_ivars_bang" args_to_ivars!(*local_vars) # works the same as .args_to_ivars, except that passing the binding is no longer required # production usage is discouraged by the creator of the supporting gem ``` ## Concerns ```ruby require "eitil_core/array" ``` ```ruby # require "eitil_core/array/map_strings" map_strings(&block) # transforms all strings in infinite recursion by yielding the given block, also works for strings contained in hashes. # call as: ["hey", ["hi", {a: "ho"}]].map_strings! { |str| str.upcase } # => ["HEY", ["HI", {a: "HO"}]] ``` ```ruby # require "eitil_core/array/map_strings" map_strings!(&block) # bang variant of .map_strings, which recursively modifies all objects it is called on. ``` ```ruby # require "eitil_core/array/slice_hashes" slice_hashes(*keys) # uses the given keys to slice each hash in the array of hashes # call as: [{"a"=>1, "b"=>2, "c"=>3}, {"a"=>1, "b"=>2, "c"=>3}].slice_hashes("a", "b") # => [{"a"=>1, "b"=>2}, {"a"=>1, "b"=>2}] ``` ## Concerns ```ruby require "eitil_core/concerns" ``` ```ruby # require "eitil_core/concerns/include_concerns_of" include_concerns_of(*directories, namespace: nil) # includes models/concerns/{directories}/* if no namespace if given, or all concerns within the given namespace # call as: include_concerns_of :user, :mail # => includes all modules of models/concerns/user/* and models/oncerns/mail/* # or call as: include_concerns_of :request_service, namespace: Eivid::Concerns # tip: call Class.included_modules to view all included modules ``` ## DateTime ```ruby require "eitil_core/datetime" ``` ```ruby # require "eitil_core/datetime/prettify" prettify # formats DateTime instances into a pretty, simple and filename friendly format # call as: DateTime.now.prettify # => "2021-04-21.17:51:42" ``` ## Errors ```ruby require "eitil_core/errors" ``` ```ruby # require "eitil_core/errors/raise_error" raise_error(_class_name, message = nil) # creates an error class if currently undefined, inheriting from StandardError, and raises the error with the given message # call as: raise_error "SomethingWentWrongError", "check your code, bro!" # => SomethingWentWrongError (check your code, bro!) ``` ## Files ```ruby require "eitil_core/files" ``` ```ruby # require "eitil_core/files/create_file" create_file(file_name, data, directory: nil, suffix: nil, file_type: nil, append: false) # writes data to a file (new or existing), with "#{Dir.home}/data" as default directory and with a timestamp as default suffix # call as: create_file('test_file', {a: 1, b: {c: 2}}, append: true) # => /Users/jurriaanschrofer/data/test_file__2021-06-30.17:30:49.json ``` ## Float ```ruby require "eitil_core/float" ``` ```ruby # require "eitil_core/float/safe_to_i" safe_to_i # converts a float to an integer, only when no decimal values are lost. # 8.00.safe_to_i returns 8 (Integer) # 8.88.safe_to_i returns 8.88 (Float) ``` ## Formatters ```ruby require "eitil_core/formatters" ``` ```ruby # require "eitil_core/formatters/duck_set" Date.duck_set(identifier) # => returns a Date instance, accepts instances of String, Date, DateTime and Time as argument DateTime.duck_set(identifier) # => returns a DateTime instance, accepts instances of String, Date, DateTime and Time as argument Time.duck_set(identifier) # => returns a Time instance, accepts instances of String, Date, DateTime and Time as argument ``` ```ruby # require "eitil_core/formatters/sql" Date.today.strfsql # => "2021-06-23" Date.today.strfsql(:date) # => "2021-06-23" DateTime.now.strfsql # => "2021-06-23 13:15:37.945083" DateTime.now.strfsql(:datetime) # => "2021-06-23 13:15:37.945083" DateTime.now.strfsql(:date) # => "2021-06-23" DateTime.now.strfsql(:time) # => "13:16:23" Time.now.strfsql # => "13:16:23" Time.now.strfsql(:datetime) # => "2021-06-23 13:15:37.945083" Time.now.strfsql(:date) # => "2021-06-23" Time.now.strfsql(:time) # => "13:16:23" ``` ## Hash ```ruby require "eitil_core/hash" ``` ```ruby # require "eitil_core/hash/auto_dig" auto_dig(_hash = self, _key) # finds the value for the given hash key, irregardless of the amount of nested layers # call as: {a: 1, b: {c: 2, d: {e: 3}}}.auto_dig :e # => 3 ``` ```ruby # require "eitil_core/hash/transform_string_values" transform_string_values(&block) # transforms all strings in infinite recursion by yielding the given block, also works for strings contained in arrays. # call as: {a: "hey", b: {c: "hi", d: ["ho"]}}.transform_string_values! { |str| str.upcase } # => {a: "HEY", b: {c: "HI", d: ["HO"]}} ``` ```ruby # require "eitil_core/hash/transform_string_values" transform_string_values!(&block) # bang variant of .transform_string_values, which recursively modifies all objects it is called on. ``` ## Kernel ```ruby require "eitil_core/kernel" ``` ```ruby # require "eitil_core/kernel/loadquire" loadquire(current_path, *relative_paths, ext: '.rb') # use .loadquire to pickup code changes on reload in development environment, while not creating overhead in production through 'load' usage # call as: loadquire __dir__, 'user' # => loads '../user.rb' in development environment, requires '../user.rb' in all other environments ``` ```ruby # require "eitil_core/kernel/loadquire_bang" loadquire!(*relative_paths, ext: '.rb') # use .loadquire! to pickup code changes on reload in development environment, while not creating overhead in production through 'load' usage # call as: loadquire! 'user' # => loads '../user.rb' in development environment, requires '../user.rb' in all other environments ``` ## Lookups ```ruby require "eitil_core/lookups" ``` ```ruby # require "eitil_core/lookups/all_methods" all_methods(include_ancestors = true, grep: nil) # pretty prints all methods for any object, grouped per type (e.g. private_methods, public_instance_methods) # call as: Class.all_methods false, grep: /json/ ``` ```ruby # require "eitil_core/lookups/gem_path" Find.gem_path(gem_name) # finds the root of an installed gem, allowing you to traverse its paths from there. # call as: Find.gem_path("rails") # => "/Users/jurriaanschrofer/.rvm/gems/ruby-2.6.5/gems/rails-5.2.3" ``` ## Mocks ```ruby require "eitil_core/mocks" ``` ```ruby # require "eitil_core/mocks/string" String.mock(n=25) # String.mock(10) # ==> "oooooo c nnnnnnnnnn ttttttttt p kkk r ppppp rrrrrrr uuu" ``` ```ruby # require "eitil_core/mocks/array" Array.mock(n=10, type=Integer, &block) # Array.mock # ==> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Array.mock(10, Float) #==> [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] # Built-in methods are provided for classes Integer, Float, String, Date, Time # But any other class is accepted as well, also your own classes such as User, Shift and Environment ``` ```ruby # require "eitil_core/mocks/hash" Hash.mock(n=10) # Hash.mock(10) #==> {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5, "f"=>6, "g"=>7, "h"=>8, "i"=>9, "j"=>10} ``` ## SafeExecutions ```ruby require "eitil_core/safe_executions" ``` ```ruby # require "eitil_core/safe_executions/safe_send" safe_send(method, *args, return_value: nil) # a safe version of .send, which in case of an error rescues and returns return_value (default: nil) instead ``` ```ruby # require "eitil_core/safe_executions/safe_call" safe_call(*args, return_value: nil, &block) # a safe version of .call, which in case of an error rescues and returns return_value (default: nil) instead # accepts either a proc argument or a block ``` ## Setters ```ruby require "eitil_core/setters" ``` ```ruby # require "eitil_core/setters/set_ivars" set_ivars(*ivars) # sets instance variables named @"#{ivar}" for each symbol passed, by invoking send("set_#{ivar}") # e.g. set_ivars(:user) sets @user with the value returned by your local method .set_user # call as: set_ivars :user, :authentication, :connection ``` ## String ```ruby require "eitil_core/string" ``` ```ruby # require "eitil_core/string/colorize" # formats strings, so that they are styled when printed to the terminal. 'hi'.black 'hi'.red 'hi'.green 'hi'.brown 'hi'.blue 'hi'.magenta 'hi'.cyan 'hi'.gray 'hi'.bg_black 'hi'.bg_red 'hi'.bg_green 'hi'.bg_brown 'hi'.bg_blue 'hi'.bg_magenta 'hi'.bg_cyan 'hi'.bg_gray 'hi'.bold 'hi'.italic 'hi'.underline 'hi'.blink 'hi'.reverse_color ``` ```ruby # require "eitil_core/string/strip_base64_header" strip_base64_header # uses a regex to remove leading base64 header data if present, e.g. "data:image/jpeg;base64," ``` ```ruby # require "eitil_core/string/to_filename" to_filename(substitute = "_") # gsub all path obtrusive characters from a string (such as [' ', '/', "\\"], stored in EitilStore::Array::PathObtrusiveCharacters) # "this is/not a very/nice file/name".to_filename => "this_is_not_a_very_nice_file_name" ``` ## TypeCheckers ```ruby require "eitil_core/type_checkers" ``` ```ruby # require "eitil_core/type_checkers/is_num_or_nan" is_num? # returns true if a string matches the Rubinius source code regex for strings and integers, false otherwise # comes in handy since ruby plays it safe on string to number conversion ('aaa'.to_f returns 0.0, thus is valid) # this method is also implemented for all other classes, such as Integer, Float, NilClass, TrueClass, Hash and so on... is_nan? # returns true if a string does NOT match the Rubinius source code regex for strings and integers, false otherwise # comes in handy since ruby plays it safe on string to number conversion ('aaa'.to_f returns 0.0, thus is valid) # this method is also implemented for all other classes, such as Integer, Float, NilClass, TrueClass, Hash and so on... ``` ## Validations ```ruby require "eitil_core/validations" ``` ```ruby # require "eitil_core/validations/run_validations" run_validations(*validations) # calls a method for each argument, namespaced as "validate_#{argument}" # call as: run_validations(:single_receipt, :single_order) # => calls #validate_single_receipt and #validate_single_order ```