Class: RecordCollection::Base
- Inherits:
-
Object
- Object
- RecordCollection::Base
- Includes:
- ActiveAttr::Model, Enumerable
- Defined in:
- lib/record_collection/base.rb
Instance Attribute Summary collapse
-
#collection ⇒ Object
readonly
Returns the value of attribute collection.
Class Method Summary collapse
- .after_record_update(&blk) ⇒ Object
- .all(*args) ⇒ Object
- .before_record_update(&blk) ⇒ Object
-
.find(ids) ⇒ Object
FINDERS.
- .human_attribute_name(*args) ⇒ Object
-
.joins(*args) ⇒ Object
Create a new collection with the scope set to the result of the query on the record_class.
- .model_name ⇒ Object
- .old_validates ⇒ Object
-
.record_class ⇒ Object
GETTER.
-
.record_class=(klass) ⇒ Object
SETTER.
- .validates(attr, options) ⇒ Object
-
.where(*args) ⇒ Object
Create a new collection with the scope set to the result of the query on the record_class.
Instance Method Summary collapse
-
#changed_attributes ⇒ Object
Return a hash of the changed attributes of the collection: { name: ‘Ben’, .…etc… }.
-
#each(&block) ⇒ Object
implement enumerable logic for collection.
- #ids ⇒ Object
-
#initialize(collection = [], params = {}) ⇒ Base
constructor
A new instance of Base.
-
#model_name ⇒ Object
delegate model name to class.
-
#not(*args) ⇒ Object
update existing scope with new one having applied not clause if possible.
- #persisted? ⇒ Boolean
- #save ⇒ Object
- #to_ary ⇒ Object
-
#uniform_collection_attribute(attr, options = {}) ⇒ Object
This method returns nil when the values of
attrin the collection are mixed. - #update(attributes) ⇒ Object
- #update_collection_attributes! ⇒ Object
-
#where(*args) ⇒ Object
update existing scope with new one having applied where clause if possible.
Constructor Details
#initialize(collection = [], params = {}) ⇒ Base
81 82 83 84 |
# File 'lib/record_collection/base.rb', line 81 def initialize(collection = [], params = {}) super(params) # active attr initialize with params @collection = collection end |
Instance Attribute Details
#collection ⇒ Object (readonly)
Returns the value of attribute collection.
6 7 8 |
# File 'lib/record_collection/base.rb', line 6 def collection @collection end |
Class Method Details
.after_record_update(&blk) ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/record_collection/base.rb', line 38 def after_record_update(&blk) if blk @after_record_update = blk else @after_record_update end end |
.all(*args) ⇒ Object
76 77 78 |
# File 'lib/record_collection/base.rb', line 76 def all(*args) self.new(record_class.all(*args)) end |
.before_record_update(&blk) ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/record_collection/base.rb', line 30 def before_record_update(&blk) if blk @before_record_update = blk else @before_record_update end end |
.find(ids) ⇒ Object
FINDERS
56 57 58 59 60 61 62 63 64 |
# File 'lib/record_collection/base.rb', line 56 def find(ids) raise "Cannot call find on a collection object if there is no record_class defined" unless respond_to?(:record_class) && record_class collection = case ids.presence when String then record_class.find(ids.split(RecordCollection.ids_separator)) when nil then [] else record_class.find(Array.wrap(ids)) end self.new(collection) end |
.human_attribute_name(*args) ⇒ Object
14 15 16 17 |
# File 'lib/record_collection/base.rb', line 14 def human_attribute_name(*args) raise "No record_class defined and could not be inferred based on the inheritance namespace. Please define self.record_clas = ClassNameOfIndividualRecords in the collection" unless record_class.present? record_class.human_attribute_name(*args) end |
.joins(*args) ⇒ Object
Create a new collection with the scope set to the result of the query on the record_class
72 73 74 |
# File 'lib/record_collection/base.rb', line 72 def joins(*args) self.new(record_class.joins(*args)) end |
.model_name ⇒ Object
10 11 12 |
# File 'lib/record_collection/base.rb', line 10 def model_name RecordCollection::Name.new(self) end |
.old_validates ⇒ Object
46 |
# File 'lib/record_collection/base.rb', line 46 alias_method :old_validates, :validates |
.record_class ⇒ Object
GETTER
20 21 22 23 |
# File 'lib/record_collection/base.rb', line 20 def record_class return @record_class if defined?(@record_class) @record_class = name.deconstantize.safe_constantize end |
.record_class=(klass) ⇒ Object
SETTER
26 27 28 |
# File 'lib/record_collection/base.rb', line 26 def record_class=(klass) @record_class = klass end |
.validates(attr, options) ⇒ Object
47 48 49 50 51 52 53 |
# File 'lib/record_collection/base.rb', line 47 def validates(attr, ) # Collection nil attributes mean they do not play a role for the collection. # So validating when the value is nil is not the default behaviour. I to be turned on explicitly # by specifying allow_nil: false [:allow_nil] = true unless .has_key?(:allow_nil) old_validates attr, end |
.where(*args) ⇒ Object
Create a new collection with the scope set to the result of the query on the record_class
67 68 69 |
# File 'lib/record_collection/base.rb', line 67 def where(*args) self.new(record_class.where(*args)) end |
Instance Method Details
#changed_attributes ⇒ Object
Return a hash of the changed attributes of the collection:
{
name: 'Ben',
....etc...
}
136 137 138 |
# File 'lib/record_collection/base.rb', line 136 def changed_attributes @changed_attributes ||= attributes.reject{|attr, val| val.nil? } end |
#each(&block) ⇒ Object
implement enumerable logic for collection
87 88 89 90 91 92 93 94 95 |
# File 'lib/record_collection/base.rb', line 87 def each(&block) collection.each do |record| if block_given? block.call record else yield record end end end |
#ids ⇒ Object
173 174 175 |
# File 'lib/record_collection/base.rb', line 173 def ids @ids ||= map{|record| record.try(:id) }.compact end |
#model_name ⇒ Object
delegate model name to class
178 179 180 |
# File 'lib/record_collection/base.rb', line 178 def model_name self.class.model_name end |
#not(*args) ⇒ Object
update existing scope with new one having applied not clause if possible
189 190 191 192 |
# File 'lib/record_collection/base.rb', line 189 def not(*args) @collection = @collection.not(*args) self end |
#persisted? ⇒ Boolean
140 141 142 143 |
# File 'lib/record_collection/base.rb', line 140 def persisted? # Behave like an update in forms, this triggers plural routes false end |
#save ⇒ Object
97 98 99 |
# File 'lib/record_collection/base.rb', line 97 def save valid? && update_collection_attributes! end |
#to_ary ⇒ Object
145 146 147 |
# File 'lib/record_collection/base.rb', line 145 def to_ary(*) self end |
#uniform_collection_attribute(attr, options = {}) ⇒ Object
This method returns nil when the values of attr in the collection are mixed. Otherwise the value itself. For boolean attributes the check is wether the values are truthy or falsy. If the
set_if_nil: true
option is given, a uniform value will be set as the collection value if it is not already set. This is important since there might be a uniform value in the collection, but the values of the collection are a result of an invalid form submission. In this case you want to keep the values of the submitted form as collection values, not the current uniform attribute.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/record_collection/base.rb', line 158 def uniform_collection_attribute(attr, = {}) attribute_spec = self.class.attributes[attr] raise "Attribute #{attr} not defined on collection" unless attribute_spec if attribute_spec[:type] == Boolean # For boolean attributes presence is the true or false difference # not the value itself results = map{|r| r.public_send(attr).present? }.uniq else results = map{|r| r.public_send(attr) }.uniq end return nil unless results.size == 1 # one value found public_send("#{attr}=", results.first) if [:set_if_nil] and public_send(attr).nil? # set value on the object if it is uniform and not yet set results.first end |
#update(attributes) ⇒ Object
101 102 103 104 |
# File 'lib/record_collection/base.rb', line 101 def update(attributes) self.attributes = attributes save end |
#update_collection_attributes! ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/record_collection/base.rb', line 106 def update_collection_attributes! after_blk = self.class.after_record_update before_blk = self.class.before_record_update each do |record| if before_blk #before_blk = before_blk.to_proc unless before_blk.is_a?(Proc) # Allow symbol to proc without cumbersome notation if before_blk.arity.zero? record.instance_eval(&before_blk) else before_blk.call(record) end end record.update changed_attributes if after_blk #after_blk = after_blk.to_proc unless after_blk.is_a?(Proc) # Allow symbol to proc without cumbersome notation if after_blk.arity.zero? record.instance_eval(&after_blk) else after_blk.call(record) end end end self end |
#where(*args) ⇒ Object
update existing scope with new one having applied where clause if possible
183 184 185 186 |
# File 'lib/record_collection/base.rb', line 183 def where(*args) @collection = @collection.where(*args) self end |