Class: TaliaCore::SemanticCollectionWrapper
- Includes:
- Enumerable
- Defined in:
- lib/talia_core/semantic_collection_wrapper.rb
Overview
Class for the collection of elements returned by the “semantic accessor” methods of a source (e.g. source)
Each wrapper contains the values for one predicate of one source (that is, for all triples of the form <thesource> <thepredicate> ?object).
The wrapper will lazy-load the data and only do a query to the database once the items are actually requested. If a database request is necessary, all data will be fetched in a single request.
Modifications of the wrapper will happen in memory. Only when the wrapper is saved using #save_items! will the modifications be written to the data store. #save_items! will be called by the “owning” source of this wrapper when the source is being saved.
Some of the methods work on the values, and other on the objects of the collection. See SemanticCollectionItem#value and SemanticCollectionItem#object for more on that.
Instance Attribute Summary collapse
-
#force_type ⇒ Object
readonly
Returns the value of attribute force_type.
Class Method Summary collapse
-
.special_types ⇒ Object
Simple hash that checks if a type if property requires “special” handling This will cause the wrapper to accept ActiveSource relations and all sources will be casted to the given type.
Instance Method Summary collapse
-
#add_record(value, order = nil) ⇒ Object
(also: #<<, #concat)
Creates a record for a value and adds it.
-
#at(index) ⇒ Object
(also: #[])
Get the element value at the given index.
-
#clean? ⇒ Boolean
Indicates that the wraper is “clean”, that is it hasn’t been written to or read from.
-
#collect ⇒ Object
Collect method for the semantic wrapper, iterating over the values of the collection.
-
#each ⇒ Object
Iterates over each value of the items in the relation.
-
#each_item ⇒ Object
Iterates of each object of the items in the relation.
- #empty? ⇒ Boolean
-
#first ⇒ Object
The first value in the collection.
-
#get_item_at(index) ⇒ Object
Gets the object at the given index.
-
#include?(value) ⇒ Boolean
Check if the collection includes the value given.
-
#index(value) ⇒ Object
Index of the given value.
-
#init_as_empty! ⇒ Object
Forces this relation to be empty.
-
#initialize(source, predicate) ⇒ SemanticCollectionWrapper
constructor
Initialize the collection with the given source and predicate.
-
#insert_item(item) ⇒ Object
Insert a new relation directly.
-
#join(join_str = ', ') ⇒ Object
Joins the values of the colle ction into a string.
-
#last ⇒ Object
The last value in the collection.
-
#loaded? ⇒ Boolean
Indicates of the internal collection is loaded.
-
#remove(*params) ⇒ Object
Remove the given value.
-
#replace(*new_values) ⇒ Object
Replace the contents of the current wrapper with the values passed.
-
#replace_value(old_value, new_value) ⇒ Object
Replace a value with a new one.
-
#save_items! ⇒ Object
This attempts to save the items to the database.
-
#size ⇒ Object
Size of the collection.
-
#values ⇒ Object
Returns an array with all values in the collection.
-
#values_with_lang(language = 'en') ⇒ Object
Returns only the values of the given language.
Constructor Details
#initialize(source, predicate) ⇒ SemanticCollectionWrapper
Initialize the collection with the given source and predicate. No database will take place during creation of the object
38 39 40 41 42 43 44 45 46 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 38 def initialize(source, predicate) @assoc_source = source @assoc_predicate = if(predicate.respond_to?(:uri)) predicate.uri.to_s else predicate.to_s end @force_type = self.class.special_types[@assoc_predicate] end |
Instance Attribute Details
#force_type ⇒ Object (readonly)
Returns the value of attribute force_type.
25 26 27 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 25 def force_type @force_type end |
Class Method Details
.special_types ⇒ Object
Simple hash that checks if a type if property requires “special” handling This will cause the wrapper to accept ActiveSource relations and all sources will be casted to the given type
30 31 32 33 34 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 30 def self.special_types @special_types ||= { N::RDF.type.to_s => N::SourceClass } end |
Instance Method Details
#add_record(value, order = nil) ⇒ Object Also known as: <<, concat
Creates a record for a value and adds it. This will add the given value if it is a database record and otherwise create a property with the given value.
If a block is given, it will be called with the new element after the new element has been added to the collection. If value is a collection, the block will be called for each element of the collection.
The order, if not nil, can be used to have a fixed order of SemanticRelation records. This is mainly used by the Collection class
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 161 def add_record(value, order = nil) raise(ArgumentError, "Blank value assigned") if(value.blank? && !value.is_a?(Enumerable)) # We use order exclusively for "ordering" predicates assit_equal(TaliaCore::Collection.index_to_predicate(order), @assoc_predicate) if(order) value = [ value ] unless(value.kind_of?(Array)) value.each do |val| rel = create_predicate(val) rel.rel_order = order if(order) block_given? ? yield(rel) : insert_item(rel) end end |
#at(index) ⇒ Object Also known as: []
Get the element value at the given index. See also SemanticCollectionItem#value
50 51 52 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 50 def at(index) items.at(index).value if(items.at(index)) end |
#clean? ⇒ Boolean
Indicates that the wraper is “clean”, that is it hasn’t been written to or read from
245 246 247 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 245 def clean? @items.nil? end |
#collect ⇒ Object
Collect method for the semantic wrapper, iterating over the values of the collection
80 81 82 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 80 def collect items.collect { |item| yield(item.value) } end |
#each ⇒ Object
Iterates over each value of the items in the relation.
74 75 76 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 74 def each items.each { |item| yield(item.value) } end |
#each_item ⇒ Object
Iterates of each object of the items in the relation.
85 86 87 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 85 def each_item items.each { |item| yield(item.object) } end |
#empty? ⇒ Boolean
249 250 251 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 249 def empty? self.size == 0 end |
#first ⇒ Object
The first value in the collection
56 57 58 59 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 56 def first item = items.first item ? item.value : nil end |
#get_item_at(index) ⇒ Object
Gets the object at the given index. See SemanticCollectionItem#object
69 70 71 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 69 def get_item_at(index) items.at(index).object if(items.at(index)) end |
#include?(value) ⇒ Boolean
Check if the collection includes the value given
148 149 150 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 148 def include?(value) items.include?(value) end |
#index(value) ⇒ Object
Index of the given value
143 144 145 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 143 def index(value) items.index(value) end |
#init_as_empty! ⇒ Object
Forces this relation to be empty. This initializes the relation, assuming that no data exists in the database. The collection will be empty, and the database will not be queried.
Warning Only call this if you need an empty wrapper and you are sure that there are no corresponding values in the database
259 260 261 262 263 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 259 def init_as_empty! raise(ArgumentError, "Already initialized!") if(loaded?) @items = [] @loaded = true end |
#insert_item(item) ⇒ Object
Insert a new relation directly. To be used with care!
266 267 268 269 270 271 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 266 def insert_item(item) # :nodoc: raise(ArgumentError, "Can only insert a SemanticRelation") unless(item.is_a?(SemanticRelation)) raise(ArgumentError, "New relation does not match the predicate of the wrapper") if(item.predicate_uri != @assoc_predicate.to_s) @items ||= [] @items << item end |
#join(join_str = ', ') ⇒ Object
Joins the values of the colle ction into a string
137 138 139 140 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 137 def join(join_str = ', ') strs = items.collect { |item| item.value.to_s } strs.join(join_str) end |
#last ⇒ Object
The last value in the collection
62 63 64 65 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 62 def last item = items.last item ? item.value : nil end |
#loaded? ⇒ Boolean
Indicates of the internal collection is loaded
239 240 241 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 239 def loaded? @loaded end |
#remove(*params) ⇒ Object
Remove the given value. With no parameters, the whole list will be cleared and the RDF will be updated immediately (!).
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 207 def remove(*params) if(params.length > 0) params.each { |par| remove_relation(par) } else if(loaded?) items.each { |item| item.destroy } else SemanticRelation.destroy_all( :subject_id => @assoc_source.id, :predicate_uri => @assoc_predicate ) end @assoc_source.my_rdf.remove(@assoc_predicate.to_uri) unless(@assoc_source.uri.to_s.blank?) @items = [] @loaded = true end end |
#replace(*new_values) ⇒ Object
Replace the contents of the current wrapper with the values passed. Blank values are ignored by this method. If non new values are passed (or all values are blank), this will simply
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 189 def replace(*new_values) new_values.flatten! if(new_values.first.is_a?(Array)) # Flatten if used as #replace([a, b, c]) new_values.reject! { |v| v.blank? } new_values.collect! { |v| create_predicate(v) } remaining_items = [] items.each do |item| if(new_values.include?(item)) remaining_items << item new_values.delete(item) else item.destroy end end @items = remaining_items + new_values end |
#replace_value(old_value, new_value) ⇒ Object
Replace a value with a new one. Equivalent to removing the old value and adding the new one
179 180 181 182 183 184 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 179 def replace_value(old_value, new_value) idx = items.index(old_value) items[idx].destroy # Creates a new relation and adds it in the place of the old one add_record(new_value) { |new_item| items[idx] = new_item } end |
#save_items! ⇒ Object
This attempts to save the items to the database. This will do nothing if the collection was never loaded to memory. It also tries to ignore data that is known to already exist in the data store and only write the records could actually have been modified.
229 230 231 232 233 234 235 236 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 229 def save_items! return if(clean?) # If there are no items, nothing was modified @assoc_source.save! unless(@assoc_source.id) @items.each do |item| item.save! end @items = nil unless(loaded?) # Otherwise we'll have trouble reload-and merging end |
#size ⇒ Object
Size of the collection
123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 123 def size return items.size if(loaded?) if(@items) # This is not really possible without loading, so we do it load! items.size else SemanticRelation.count(:conditions => { 'subject_id' => @assoc_source.id, 'predicate_uri' => @assoc_predicate }) end end |
#values ⇒ Object
Returns an array with all values in the collection
90 91 92 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 90 def values items.collect { |item| item.value } end |
#values_with_lang(language = 'en') ⇒ Object
Returns only the values of the given language. (At the moment this is not aware of region codes or any specialities, it just does a string matching)
If no values with the given locale are found, this will fall back on the default locale and then to the values that don’t have a locale at all.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/talia_core/semantic_collection_wrapper.rb', line 101 def values_with_lang(language = 'en') language_is_default = (language == I18n.default_locale.to_s) real = [] default = [] unset = [] items.each do |item| # FIXME: At the moment, this only works for value attributes, not for # sources if((val = item.value).respond_to?(:lang)) real << val if(val.lang == language) default << val if(!language_is_default && (val.lang == I18n.default_locale.to_s)) unset << val if(val.lang.blank?) else default << val end end return real unless(real.empty?) return default unless(default.empty?) unset end |