Module: UsefulUtilities::AR
Overview
ActiveRecord utilities
Defined Under Namespace
Modules: Methods
Constant Summary collapse
- NESTED_ASSOCIATIONS =
%i( has_one has_many )
- BASE_ERROR_KEY =
:base
- TYPE_SUFFIX =
'%s_type'
- ID_SUFFIX =
'%s_id'
Instance Method Summary collapse
-
#[](klass, *columns) ⇒ String
Qualified columns splitted by comma.
-
#asc(klass, column) ⇒ String
ASC statement for ORDER BY.
-
#boolean_to_float(value) ⇒ Float
Value as float.
- #by_polymorphic(scope, key, value) ⇒ ActiveRecord::Relation
-
#ceil(value) ⇒ Object
CEILING statement.
-
#count(klass, column, result) ⇒ String
Count statement.
-
#deep_validation(record) ⇒ Object
Validates record and associations.
-
#delete_dependents(owner, self_class, dependent_class) ⇒ Object
Deletes dependent records.
-
#desc(klass, column) ⇒ String
DESC statement for ORDER BY.
-
#nested_associations_validation(record, nested = false) ⇒ Object
Validates nested associations of a record.
-
#null_to_zero(*args) ⇒ Object
COALESCE statement.
- #older_than(scope, _value) ⇒ ActiveRecord::Relation
-
#sql_sum(*args, result) ⇒ Object
SUM statement.
-
#sum_by_columns(scope, *all_columns) ⇒ Object
Can be used for not NULL columns only sum_by_columns(Virtual, :column_1, :column2, column3: :column3_alias…).
- #to_polymorphic_type(value) ⇒ Object
-
#value_to_boolean(value) ⇒ Boolean
Value as boolean.
-
#value_to_decimal(value) ⇒ BigDecimal
Value as BigDecimal.
-
#value_to_integer(value) ⇒ Integer
Value as Integer.
Instance Method Details
#[](klass, *columns) ⇒ String
Returns qualified columns splitted by comma.
114 115 116 |
# File 'lib/useful_utilities/ar.rb', line 114 def [](klass, *columns) columns.map { |column| "#{ klass.table_name }.#{ column }" }.join(', ') end |
#asc(klass, column) ⇒ String
Returns ASC statement for ORDER BY.
121 122 123 |
# File 'lib/useful_utilities/ar.rb', line 121 def asc(klass, column) "#{ self[klass, column] } ASC" end |
#boolean_to_float(value) ⇒ Float
Returns value as float.
58 59 60 |
# File 'lib/useful_utilities/ar.rb', line 58 def boolean_to_float(value) value ? 1.0 : 0.0 end |
#by_polymorphic(scope, key, value) ⇒ ActiveRecord::Relation
92 93 94 95 96 |
# File 'lib/useful_utilities/ar.rb', line 92 def by_polymorphic(scope, key, value) type = to_polymorphic_type(value) type_column, id_column = TYPE_SUFFIX % key, ID_SUFFIX % key scope.where(type_column => type, id_column => value) end |
#ceil(value) ⇒ Object
Returns CEILING statement.
156 157 158 |
# File 'lib/useful_utilities/ar.rb', line 156 def ceil(value) "CEILING(#{value})" end |
#count(klass, column, result) ⇒ String
Returns count statement.
191 192 193 |
# File 'lib/useful_utilities/ar.rb', line 191 def count(klass, column, result) "COUNT(#{ self[klass, column] }) AS #{ result }" end |
#deep_validation(record) ⇒ Object
Validates record and associations
64 65 66 67 |
# File 'lib/useful_utilities/ar.rb', line 64 def deep_validation(record) record.valid? nested_associations_validation(record) end |
#delete_dependents(owner, self_class, dependent_class) ⇒ Object
Deletes dependent records
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/useful_utilities/ar.rb', line 199 def delete_dependents(owner, self_class, dependent_class) dependent_fk = dependent_class.foreign_key(self_class) self_fk = self_class.foreign_key(owner.class) "DELETE #{dependent_class.table_name} FROM #{dependent_class.table_name} INNER JOIN #{self_class.table_name} ON #{self[dependent_class, dependent_fk]} = #{self[self_class, :id]} WHERE #{self[self_class, self_fk]} = #{owner.id}" end |
#desc(klass, column) ⇒ String
Returns DESC statement for ORDER BY.
128 129 130 |
# File 'lib/useful_utilities/ar.rb', line 128 def desc(klass, column) "#{ self[klass, column] } DESC" end |
#nested_associations_validation(record, nested = false) ⇒ Object
Validates nested associations of a record
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/useful_utilities/ar.rb', line 72 def nested_associations_validation(record, nested = false) record.class.reflections.each do |name, reflection| next unless NESTED_ASSOCIATIONS.include?(reflection.macro) association_records = Array(record.public_send(name)) error_key = nested ? BASE_ERROR_KEY : name record.errors.delete(name) association_records.each do |nested_record| next unless nested_record.changed? nested_associations_validation(nested_record, :nested) nested_record.errors..each { || record.errors[error_key] << } end end end |
#null_to_zero(*args) ⇒ Object
Returns COALESCE statement.
142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/useful_utilities/ar.rb', line 142 def null_to_zero(*args) sql_column = case args.size when 1 then args.first when 2 then self[args[0], args[1]] else raise ArgumentError, "wrong number of arguments (#{ args.size } for 1..2)" end "COALESCE(#{ sql_column }, 0)" end |
#older_than(scope, _value) ⇒ ActiveRecord::Relation
135 136 137 138 |
# File 'lib/useful_utilities/ar.rb', line 135 def older_than(scope, _value) value = _value.is_a?(ActiveRecord::Base) ? _value.id : _value value.present? ? scope.where("#{ self[scope, :id] } < ?", value) : scope end |
#sql_sum(*args, result) ⇒ Object
Returns SUM statement.
163 164 165 |
# File 'lib/useful_utilities/ar.rb', line 163 def sql_sum(*args, result) "SUM(#{ null_to_zero(*args) }) AS #{ result }" end |
#sum_by_columns(scope, *all_columns) ⇒ Object
Can be used for not NULL columns only sum_by_columns(Virtual, :column_1, :column2, column3: :column3_alias…)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/useful_utilities/ar.rb', line 171 def sum_by_columns(scope, *all_columns) columns = all_columns.flatten columns_with_aliases = columns. sql_query = columns.reduce(columns_with_aliases) do |res, column| res.merge!(column => column) end. map do |column, column_alias| "COALESCE(SUM(#{ column }), 0) AS #{ column_alias }" end. join(', ') scope.select(sql_query).first end |
#to_polymorphic_type(value) ⇒ Object
101 102 103 104 105 106 107 108 109 |
# File 'lib/useful_utilities/ar.rb', line 101 def to_polymorphic_type(value) klass = if value.is_a?(Class) || value.nil? then value elsif value.respond_to?(:klass) then value.klass else value.class end klass.respond_to?(:base_class) ? klass.base_class : klass end |
#value_to_boolean(value) ⇒ Boolean
Returns value as boolean.
47 48 49 50 51 |
# File 'lib/useful_utilities/ar.rb', line 47 def value_to_boolean(value) return false if value.nil? ActiveRecord::Type::Boolean.new.type_cast_from_database(value) end |
#value_to_decimal(value) ⇒ BigDecimal
Returns value as BigDecimal.
39 40 41 42 43 |
# File 'lib/useful_utilities/ar.rb', line 39 def value_to_decimal(value) return BigDecimal.new(0) if value.nil? ActiveRecord::Type::Decimal.new.type_cast_from_database(value) end |
#value_to_integer(value) ⇒ Integer
Returns value as Integer.
29 30 31 32 33 34 35 |
# File 'lib/useful_utilities/ar.rb', line 29 def value_to_integer(value) return 0 if value.nil? return 0 if value == false return 1 if value == true ActiveRecord::Type::Integer.new.type_cast_from_database(value) end |