Class TaliaCore::SemanticCollectionWrapper
In: lib/talia_core/semantic_collection_wrapper.rb
Parent: Object

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.

Methods

'<<'   []   add_record   at   clean?   collect   concat   each   each_item   empty?   first   get_item_at   include?   index   init_as_empty!   join   last   loaded?   new   remove   replace   replace_value   save_items!   size   special_types   values   values_with_lang  

Included Modules

Enumerable

Attributes

force_type  [R] 

Public Class methods

Initialize the collection with the given source and predicate. No database will take place during creation of the object

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 38
38:     def initialize(source, predicate)
39:       @assoc_source = source
40:       @assoc_predicate = if(predicate.respond_to?(:uri))
41:         predicate.uri.to_s
42:       else
43:         predicate.to_s
44:       end
45:       @force_type = self.class.special_types[@assoc_predicate]
46:     end

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

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 30
30:     def self.special_types
31:       @special_types ||= {
32:         N::RDF.type.to_s => N::SourceClass
33:       }
34:     end

Public Instance methods

'<<'(value, order = nil)

Alias for add_record

[](index)

Alias for at

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

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 161
161:       def add_record(value, order = nil)
162:         raise(ArgumentError, "Blank value assigned") if(value.blank? && !value.is_a?(Enumerable))
163:         # We use order exclusively for "ordering" predicates
164:         assit_equal(TaliaCore::Collection.index_to_predicate(order), @assoc_predicate) if(order)
165: 
166:         value = [ value ] unless(value.kind_of?(Array))
167: 
168:         value.each do |val|
169:           rel = create_predicate(val)
170:           rel.rel_order = order if(order)
171:           block_given? ? yield(rel) : insert_item(rel)
172:         end
173:       end

Get the element value at the given index. See also SemanticCollectionItem#value

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 50
50:     def at(index)
51:       items.at(index).value if(items.at(index))
52:     end

Indicates that the wraper is "clean", that is it hasn‘t been written to or read from

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 245
245:       def clean?
246:         @items.nil?
247:       end

Collect method for the semantic wrapper, iterating over the values of the collection

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 80
80:     def collect
81:       items.collect { |item| yield(item.value) }
82:     end
concat(value, order = nil)

Alias for add_record

Iterates over each value of the items in the relation.

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 74
74:     def each
75:       items.each { |item| yield(item.value) }
76:     end

Iterates of each object of the items in the relation.

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 85
85:     def each_item
86:       items.each { |item| yield(item.object) }
87:     end

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 249
249:       def empty?
250:         self.size == 0
251:       end

The first value in the collection

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 56
56:     def first
57:       item = items.first
58:       item ? item.value : nil
59:     end

Gets the object at the given index. See SemanticCollectionItem#object

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 69
69:     def get_item_at(index)
70:       items.at(index).object if(items.at(index))
71:     end

Check if the collection includes the value given

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 148
148:       def include?(value)
149:         items.include?(value)
150:       end

Index of the given value

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 143
143:       def index(value)
144:         items.index(value)
145:       end

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

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 259
259:       def init_as_empty!
260:         raise(ArgumentError, "Already initialized!") if(loaded?)
261:         @items = []
262:         @loaded = true
263:       end

Joins the values of the colle ction into a string

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 137
137:       def join(join_str = ', ')
138:         strs = items.collect { |item| item.value.to_s }
139:         strs.join(join_str)
140:       end

The last value in the collection

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 62
62:     def last
63:       item = items.last
64:       item ? item.value : nil
65:     end

Indicates of the internal collection is loaded

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 239
239:       def loaded?
240:         @loaded
241:       end

Remove the given value. With no parameters, the whole list will be cleared and the RDF will be updated immediately (!).

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 207
207:       def remove(*params)
208:         if(params.length > 0)
209:           params.each { |par| remove_relation(par) }
210:         else
211:           if(loaded?)
212:             items.each { |item| item.destroy }
213:           else
214:             SemanticRelation.destroy_all(
215:             :subject_id => @assoc_source.id,
216:             :predicate_uri => @assoc_predicate
217:             )
218:           end
219:           @assoc_source.my_rdf.remove(@assoc_predicate.to_uri) unless(@assoc_source.uri.to_s.blank?)
220:           @items = []
221:           @loaded = true
222:         end
223:       end

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

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 189
189:       def replace(*new_values)
190:         new_values.flatten! if(new_values.first.is_a?(Array)) # Flatten if used as #replace([a, b, c])
191:         new_values.reject! { |v| v.blank? }
192:         new_values.collect! { |v| create_predicate(v) }
193:         remaining_items = []      
194:         items.each do |item|
195:           if(new_values.include?(item))
196:             remaining_items << item
197:             new_values.delete(item)
198:           else
199:             item.destroy
200:           end
201:         end
202:         @items = remaining_items + new_values
203:       end

Replace a value with a new one. Equivalent to removing the old value and adding the new one

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 179
179:       def replace_value(old_value, new_value)
180:         idx = items.index(old_value)
181:         items[idx].destroy
182:         # Creates a new relation and adds it in the place of the old one
183:         add_record(new_value) { |new_item| items[idx] = new_item }
184:       end

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.

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 229
229:       def save_items!
230:         return if(clean?) # If there are no items, nothing was modified
231:         @assoc_source.save! unless(@assoc_source.id)
232:         @items.each do |item|
233:           item.save!
234:         end
235:         @items = nil unless(loaded?) # Otherwise we'll have trouble reload-and merging
236:       end

Size of the collection

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 123
123:     def size
124:       return items.size if(loaded?)
125:       if(@items)
126:         # This is not really possible without loading, so we do it
127:         load!
128:         items.size
129:       else
130:         SemanticRelation.count(:conditions => {
131:           'subject_id' => @assoc_source.id,
132:           'predicate_uri' => @assoc_predicate })
133:         end
134:       end

Returns an array with all values in the collection

[Source]

    # File lib/talia_core/semantic_collection_wrapper.rb, line 90
90:     def values
91:       items.collect { |item| item.value }
92:     end

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.

[Source]

     # File lib/talia_core/semantic_collection_wrapper.rb, line 101
101:     def values_with_lang(language = 'en')
102:       language_is_default = (language == I18n.default_locale.to_s)
103:       real = []
104:       default = []
105:       unset = []
106:       items.each do |item|
107:         # FIXME: At the moment, this only works for value attributes, not for 
108:         # sources
109:         if((val = item.value).respond_to?(:lang))
110:           real << val if(val.lang == language)
111:           default << val if(!language_is_default && (val.lang == I18n.default_locale.to_s))
112:           unset << val if(val.lang.blank?)
113:         else
114:           default << val
115:         end
116:       end
117:       return real unless(real.empty?)
118:       return default unless(default.empty?)
119:       unset
120:     end

[Validate]