skimming 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d38d35c798f029c2f8331d2ff3f890ede872607567b65e2d4ae43dcbdc28d034
4
+ data.tar.gz: 6447c4b4c3d103c5b3458852d87216444a8bc9c985b1851ae45727678c375e38
5
+ SHA512:
6
+ metadata.gz: 715fdc5fa8d1cb0519ac9e7b6696e102f3f245ba57bf6d7d8e08e89025e0ec060691bdfdac941de84422df17cd643032e745a91c8ffec7dc83a329de212a6380
7
+ data.tar.gz: 1e6e3d3a21855d2917790f56c50bd82579ec798f1392288febea4cf94bfbf704536e9ad2c0577f498bb0a24a88e3cb8afe6f9837f7510d67e5dd809dff1d2d41
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ skimming-*
@@ -0,0 +1,41 @@
1
+ require 'rails/generators'
2
+
3
+ class SkimmingMigrationGenerator < Rails::Generators::Base
4
+
5
+ def create_migration_file
6
+ create_file "db/migrate/#{Time.zone.now.strftime("%Y%m%d%H%M%S")}_skimming_migration.rb", migration_data
7
+ end
8
+
9
+ private
10
+
11
+ def migration_data
12
+ <<MIGRATION
13
+ class SkimmingMigration < ActiveRecord::Migration[5.2]
14
+ # 0.0.1 Release
15
+ def change
16
+ unless table_exists? :collection_filters
17
+ create_table :collection_filters do |t|
18
+ t.string :object_name
19
+ t.string :rule
20
+
21
+ t.timestamps
22
+ end
23
+
24
+ #{generate_join_tables_creation_data}
25
+ end
26
+ end
27
+ end
28
+ MIGRATION
29
+ end
30
+
31
+ def generate_join_tables_creation_data
32
+ join_tables_creation_data = ""
33
+ associations = Skimming.configuration.associations.keys
34
+
35
+ associations.each do |association|
36
+ join_tables_creation_data += "create_join_table :collection_filters, :#{association}#{"\n " unless association == associations.last}"
37
+ end
38
+
39
+ join_tables_creation_data
40
+ end
41
+ end
@@ -0,0 +1,11 @@
1
+ module Skimming
2
+ class CollectionFilter < ActiveRecord::Base
3
+ Skimming.configuration.associations.each do |association_name, association_options|
4
+ has_and_belongs_to_many association_name.to_sym, class_name: association_options[:class_name], inverse_of: :collection_filters, foreign_key: "#{association_name}_id".to_sym
5
+ end
6
+
7
+ validates_presence_of :object_name, :rule
8
+
9
+ scope :for_object, -> (object_name) { where(object_name: object_name) }
10
+ end
11
+ end
data/lib/skimming.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'skimming/configuration'
2
+ require 'skimming/model'
3
+ require 'skimming/parasite_model'
4
+ require 'skimming/skimmer'
5
+ require 'models/skimming/collection_filter'
6
+ require 'generators/skimming_migration_generator'
@@ -0,0 +1,18 @@
1
+ module Skimming
2
+ def self.configuration
3
+ @configuration ||= Configuration.new(configuration_hash)
4
+ end
5
+
6
+ def self.configuration_hash
7
+ @configuration_hash ||= HashWithIndifferentAccess.new(YAML.load_file('config/skimming.yml'))
8
+ end
9
+
10
+ class Configuration
11
+ attr_accessor :associations, :options
12
+
13
+ def initialize(configuration_hash)
14
+ @associations = configuration_hash[:associations]
15
+ @options = configuration_hash[:options]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module Skimming
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_and_belongs_to_many :collection_filters, class_name: 'Skimming::CollectionFilter'
7
+ end
8
+
9
+ def skim(collection, object_name: nil, **skimming_instances)
10
+ Skimming::Skimmer.new(self, collection, object_name, skimming_instances).skim
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module Skimming
2
+ module ParasiteModel
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ Skimming.configuration.options[name.demodulize.underscore][:skim_through].each do |association_name|
7
+ has_many :collection_filters, through: association_name.to_sym, class_name: 'Skimming::CollectionFilter'
8
+ end
9
+ end
10
+
11
+ def skim(collection, through: nil, object_name: nil, **skimming_instances)
12
+ Skimming::Skimmer.new(self, collection, object_name, skimming_instances).skim_through through
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,59 @@
1
+ module Skimming
2
+ class Skimmer
3
+ attr_reader :subject, :collection, :collection_name, :skimming_instances
4
+
5
+ def initialize(subject, collection, object_name, skimming_instances)
6
+ @subject = subject
7
+ @collection = collection
8
+ @collection_name = object_name || calculate_collection_name
9
+ @skimming_instances = skimming_instances
10
+ end
11
+
12
+ def skim
13
+ set_instance_variables
14
+
15
+ filters_rules = subject.collection_filters.for_object(collection_name).map(&:rule)
16
+
17
+ return collection if filters_rules.empty?
18
+
19
+ skimming_result = collection.select do |collection_object|
20
+ instance_variable_set("@#{collection_object.class.name.downcase}", collection_object)
21
+
22
+ filters_rules.all? { |rule| eval rule }
23
+ end
24
+
25
+ skimming_result
26
+ end
27
+
28
+ def skim_through(skimming_associations)
29
+ set_instance_variables
30
+
31
+ skimming_associations = Skimming.configuration.options[subject.class.name.underscore][:skim_through] if skimming_associations.blank?
32
+ skimming_result = []
33
+
34
+ skimming_associations.each do |association_name|
35
+ subject.send(association_name.to_sym).each do |skimming_object|
36
+ skimming_result += skimming_object.skim(collection, subject.class.name.downcase.to_sym => subject)
37
+ end
38
+ end
39
+
40
+ skimming_result.uniq
41
+ end
42
+
43
+ private
44
+
45
+ def calculate_collection_name
46
+ raise 'Invalid collection: contains objects with different classes' unless collection.map(&:class).uniq.count == 1
47
+
48
+ collection.first.class.name.downcase
49
+ end
50
+
51
+ def set_instance_variables
52
+ instance_variable_set("@#{subject.class.name.downcase}", subject)
53
+
54
+ skimming_instances.each do |instance_name, instance_object|
55
+ instance_variable_set("@#{instance_name}", instance_object)
56
+ end
57
+ end
58
+ end
59
+ end
data/skimming.gemspec ADDED
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'skimming'
3
+ s.version = '0.0.1'
4
+ s.date = '2020-04-18'
5
+ s.summary = "Collections skimming"
6
+ s.description = "Filter your collections with database-configurable rules"
7
+ s.authors = ["Valerio Bellaveglia"]
8
+ s.files = `git ls-files`.split("\n")
9
+ s.homepage = 'https://github.com/ValerioBellaveglia/Skimming'
10
+ s.require_path = 'lib'
11
+ s.license = 'MIT'
12
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skimming
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Valerio Bellaveglia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Filter your collections with database-configurable rules
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ".gitignore"
20
+ - lib/generators/skimming_migration_generator.rb
21
+ - lib/models/skimming/collection_filter.rb
22
+ - lib/skimming.rb
23
+ - lib/skimming/configuration.rb
24
+ - lib/skimming/model.rb
25
+ - lib/skimming/parasite_model.rb
26
+ - lib/skimming/skimmer.rb
27
+ - skimming.gemspec
28
+ homepage: https://github.com/ValerioBellaveglia/Skimming
29
+ licenses:
30
+ - MIT
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.0.2
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Collections skimming
51
+ test_files: []