By Combinaut.
LaForge is a gem that makes it easy to build records using data from several data sources. It aims to facilitate management of which data sources a record is assembled from, and to perform the actual data assembly in order to output a record.
Key features:
- Allows published content to be edited without those changes immediately being seen by visitors
- Can selectively update content without needing to sync the entire database with production
- Add Laforge to your Gemfile:
gem 'laforge', github: 'combinaut/laforge'
- Add laforge to your model.
# In your model
class MyModel < ApplicationModel
laforged
end
- Create some sources and prioritize them, giving higher priority to sources whose attributes should override those same attributes from lower priority sources.
source1 = LaForge::DataSource.create(name: 'Encyclopedia Britannica', priority: 2)
source2 = LaForge::DataSource.create(name: 'Wikipedia', priority: 1)
- Build a new model, or update an existing one with data from any of your sources.
foo = MyModel.new
foo.record_data_entries({ height: 20, width: 5 }, source1)
foo.record_data_entries({ height: 19, name: 'El Capitan' }, source2)
foo.forge! # => Saves the model with the attributes { height: 20, width: 5, name: 'El Capitan' }
Note: Calling record_data_entries
builds the Data Entries, but they are not persisted and and the record's attributes not updated until forge!
is called.
- Remove data for an existing model from any of your sources.
foo.remove_data_entries(source1)
foo.forge! # => Saves the model with the attributes { height: 19, width: nil, name: 'El Capitan' }
Note: calling remove_data_entries
marks the Data Entries for destruction, but they are not destroyed and the removed attributes not nullified until forge!
is called.
The priority of a data entry can be customized to override the priority inherited from the data source.
foo = MyModel.new
foo.record_data_entries({ height: 20, width: 5 }, source1)
foo.record_data_entries({ height: 19 }, source2, priority: 3) # Override the priority inherited from the data source
foo.forge! # => Saves the model with the attributes { height: 19, width: 5 }
MyModel.with_source(source1) # => All records from source1
MyModel.without_source(source1) # => All records not from source1
MyModel.with_attribute(:height) # => All records with a recorded height attribute from any source
MyModel.without_attribute(:height) # => All records without a recorded height attribute from any source
MyModel.with_attribute_with_source(:height, source1) # => All records with a recorded height attribute from source1
MyModel.with_attribute_with_source([:height, :width], source1) # => All records with a recorded height or width attribute from source1
MyModel.with_attribute_without_source(:height, source1) # => All records with a recorded height not from source1
MyModel.with_attribute_without_source([:height, :width], source1) # => All records with a recorded height or width attribute not from source1
MyModel.with_attribute_with_source(:height, source1).with_attribute_with_source(:width, source1) # => All records with both a recorded height and width attribute from source1
MyModel.without_attribute_with_source(:height, source1) # => All records without a recorded height attribute from source1
MyModel.without_attribute_with_source([:height, :width], source1) # => All records missing a recorded height or missing a recorded width from source1
MyModel.without_attribute_with_source(:height, source1).without_attribute_with_source(:width, source1) # => All records without both a recorded height and width attribute from source1