lca 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc53882ad2b8c5c34b869be0546546973dd829b25aa39f354e9be9da63a44fae
4
- data.tar.gz: 57c65eeadf05e7e6f160ea1c2ca3db8a025614578ecb6242d9f1404002651766
3
+ metadata.gz: 62afb1561f978b69743ea334e439cc449375f0b4bc1cad29601b174a5d231a41
4
+ data.tar.gz: 1f18a6226d1fee18f3e2d226616c34dd3cae9ba99389ef9ffb17cf828c586e34
5
5
  SHA512:
6
- metadata.gz: 2a1542ddf863b9461fb3ceb67e45f59599608c40e98994203918b7aeb4fb87ef2e4b1f73bd7fa3a837a0cd9cbd691cf72648505f38f156c64b84b6ee097d0dd6
7
- data.tar.gz: e7989620c9b0a81249e741b41bcbe8fd1854b24650d66e4963ce940ab593d8ea2340403f06f467d8e280cea3dfed99d1c5067407771557403bf2d049cf792b0c
6
+ metadata.gz: e190b6449f86a075d6582276747f6f17b1d617cf404f1db04ef7600f7ac9a84490d60535901a9b1e3fc212fb855b381fb80f78d583db391a159b27c75b63e9a3
7
+ data.tar.gz: b2fc67ead55300e549192c8f1b37e2971e11bc4da9ed08956ea46a601fc6aba1596a56106822f1b085e2c82d94560975bcc301ef8df3946121a331ddcd925a7f
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Storing, processing and working with life-cycle assessment data has always been challenging. A multitude of data models and implementations exist already but every one of them makes huge compromises or lacks functionality.
6
6
 
7
- This gem implements a denormalized database model for life-cycle assessment data as well as several innovative query interfaces.
7
+ This gem implements a denormalized database model for life-cycle assessment data as well as several vectors for convenient querying.
8
8
 
9
9
  ## Installation
10
10
 
@@ -42,42 +42,42 @@ Include the LCA concern into one of your models which will own lifecycle trees (
42
42
  This will extend your model and enable the following functionality:
43
43
 
44
44
  ```ruby
45
- # query with ActiveRecord syntax
46
- User.last.lca_cycles
47
- User.find_by(name: "Acme").lca_cycles.impacts.select("impact_unit, sum(impact_amount) as total_impact").group(:impact_unit)
48
- User.last.lca_cycles.where(...)
49
- User.last.lca_cycles.where(...).group(...)
50
- User.last.lca_cycles.where(...).limit(...).offset(...)
45
+ # query with ActiveRecord syntax
46
+ User.last.lca_cycles
47
+ User.find_by(name: "Acme").lca_cycles.impacts.select("impact_unit, sum(impact_amount) as total_impact").group(:impact_unit)
48
+ User.last.lca_cycles.where(...)
49
+ User.last.lca_cycles.where(...).group(...)
50
+ User.last.lca_cycles.where(...).limit(...).offset(...)
51
51
 
52
- # AR query with ltree syntax
53
- User.last.lca_cycles.disabled.match_path("*.CustomProcess.*")
54
- User.last.lca_cycles.match_path("*{5,10}.CustomProcess.*.Ecosphere.*")
55
- User.last.lca_cycles.active.match_path("*.WhateverProcess.*.Ecosphere.*.CO2Emission.*").where( impact_amount: [100..150]).sum(:impact_amount)
56
-
57
- Lca::Cycle.match_path("Top.Electric Vehicle.*").impacts.match_path("*.CO2*").where( impact_amount: [ 1000..10000 ]).average(:impact_amount)
58
- Lca::Cycle::Product.where(name: "Electric Vehicle Battery").impacts.match_path("*.Cobalt.*").sum(:impact_amount)
59
- Lca::Process.where(owner: User.last).match_path("*{10,20}.*Assembly, automated.*")
60
- Lca::Impact.match_path("*.Transport by truck.*")
61
- Lca::Exchange.match_path("*.Oil.*.Ecosphere.*").impacts.sum(:impact_amount)
62
- Lca::Product.match_path("*.ElectricVehicle.*").processes.match_path("*.Processing.*").where(location: "EU").impacts.match_path("*.Lithium.*").where(location: ["CN", "Africa"]).sum(:impact_amount)
52
+ # AR query with ltree syntax
53
+ User.last.lca_cycles.disabled.match_path("*.CustomProcess.*")
54
+ User.last.lca_cycles.match_path("*{5,10}.CustomProcess.*.Ecosphere.*")
55
+ User.last.lca_cycles.active.match_path("*.WhateverProcess.*.Ecosphere.*.CO2Emission.*").where( impact_amount: [100..150]).sum(:impact_amount)
56
+
57
+ Lca::Cycle.match_path("Top.Electric Vehicle.*").impacts.match_path("*.CO2*").where( impact_amount: [ 1000..10000 ]).average(:impact_amount)
58
+ Lca::Cycle::Product.where(name: "Electric Vehicle Battery").impacts.match_path("*.Cobalt.*").sum(:impact_amount)
59
+ Lca::Process.where(owner: User.last).match_path("*{10,20}.*Assembly, automated.*")
60
+ Lca::Impact.match_path("*.Transport by truck.*")
61
+ Lca::Exchange.match_path("*.Oil.*.Ecosphere.*").impacts.sum(:impact_amount)
62
+ Lca::Product.match_path("*.ElectricVehicle.*").processes.match_path("*.Processing.*").where(location: "EU").impacts.match_path("*.Lithium.*").where(location: ["CN", "Africa"]).sum(:impact_amount)
63
63
 
64
- # pg_ltree queries
65
- User.last.lca_cycles.last.parent
66
- Lca::Process.match_path("*.Manual assembly.*").children
64
+ # pg_ltree queries
65
+ User.last.lca_cycles.last.parent
66
+ Lca::Process.match_path("*.Manual assembly.*").children
67
67
 
68
- # pg_ltree combined with AR syntax
69
- User.last.lca_cycles(type: "Lca::Product").children.match_path("*.Retail").children.exchanges
68
+ # pg_ltree combined with AR syntax
69
+ User.last.lca_cycles(type: "Lca::Product").children.match_path("*.Retail").children.exchanges
70
70
 
71
- # all queries can be directed to a specific partition:
72
- Lca::Process.owned_by( owner_id ).match_path("*.Recycling.*").where(impact_unit: "tons CO2/year").impacts.sum(:impact_amount)
71
+ # all queries can be directed to a specific partition:
72
+ Lca::Process.owned_by( owner_id ).match_path("*.Recycling.*").where(impact_unit: "tons CO2/year").impacts.sum(:impact_amount)
73
73
 
74
74
  ```
75
75
 
76
76
  The gem also creates some default models:
77
77
 
78
78
  ```ruby
79
- Lca::Process::Transport::ByAir.match_path("*.CO2Emission.*").impacts.sum(:impact_amount)
80
- Lca::Impact::Ecosphere::Fauna.match_path("*.ResourceExtraction.*").where(impact_unit: "Species killed/year").sum(:impact_amount)
79
+ Lca::Process::Transport::ByAir.match_path("*.CO2Emission.*").impacts.sum(:impact_amount)
80
+ Lca::Impact::Ecosphere::Fauna.match_path("*.ResourceExtraction.*").where(impact_unit: "Species killed/year").sum(:impact_amount)
81
81
  ```
82
82
 
83
83
  To see what syntax to use for path traversal please check out the following resources:
@@ -88,6 +88,21 @@ The LCA gem is designed to be compatible with PostgREST. PostgREST is an amazing
88
88
 
89
89
  If the `create_postgrest_roles` setting is on each new owner will be assigned a Postgres role allowing them to access data within their partition using PostgREST. Your owner model will be extended with a `.generate_jwt` method you can use to generate the PostgREST authentication token.
90
90
 
91
+ ## Caveats
92
+
93
+ `pg_ltree` .child / .parent queries do not work across different models due to an ActiveRecord limitation that requires results to be related via inheritance.
94
+
95
+ The following behaviors have been observed:
96
+
97
+ ```ruby
98
+
99
+ Lca::Process.last.children.impacts.where(impact_amount: 50)
100
+ # => nil
101
+
102
+ Lca::Process.last.children.unscope(where: :type).impacts.where(impact_amount: 50)
103
+ # => ActiveRecord::SubclassNotFound (Invalid single-table inheritance type: Lca::Impact is not a subclass of Lca::Process)
104
+ ```
105
+
91
106
  ## Roadmap
92
107
 
93
108
  * .child / .parent query support across models unrelated through inheritance
@@ -14,19 +14,23 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
14
14
  id serial,
15
15
 
16
16
  owner_id integer,
17
- owner_type text,
17
+ owner_type character varying,
18
+
19
+ status integer,
18
20
 
19
- data_external_id text,
20
- data_provider text,
21
+ data_external_id character varying,
22
+ data_provider character varying,
21
23
 
22
- type text,
24
+ type character varying,
23
25
  name text,
24
26
 
25
27
  parent_entity_id integer,
26
- parent_entity_type text,
28
+ parent_entity_type character varying,
27
29
 
28
30
  path ltree,
29
31
  path_slug text,
32
+
33
+ metadata_inline jsonb,
30
34
 
31
35
  impact_amount decimal,
32
36
  impact_amount_unit text,
@@ -57,5 +61,19 @@ SQL
57
61
  execute "create role postgrest_anon nologin"
58
62
  execute "grant postgrest_anon to #{ LCA_OPTIONS[:database_user] }"
59
63
  end
64
+
65
+
66
+
67
+ #
68
+ create_table "#{ LCA_OPTIONS[:table_name] }_metadata" do |t|
69
+ t.string :model_type
70
+ t.integer :model_id
71
+ t.string :key
72
+ t.text :value
73
+
74
+ t.timestamps
75
+ end
76
+ add_index "#{ LCA_OPTIONS[:table_name] }_metadata", [ :model_type, :model_id ]
77
+ add_index "#{ LCA_OPTIONS[:table_name] }_metadata", [ :key ]
60
78
  end
61
79
  end
@@ -1,6 +1,6 @@
1
- # this still needed?
2
1
  # we include the concern manually so there should be no need for this anymore
3
- ActiveSupport.on_load(:active_record) do
4
- puts "tf is AR still being extended?"
5
- extend Lca::Lcable
6
- end
2
+ # besides, no need to polute other classes with our stuff.
3
+
4
+ # ActiveSupport.on_load(:active_record) do
5
+ # extend Lca::Lcable
6
+ # end
@@ -13,8 +13,13 @@ module Lca::Statusable
13
13
  alias_method :disable!, :inactive!
14
14
  alias_method :off!, :inactive!
15
15
  alias_method :toggle?, :toggle_status!
16
+
17
+ before_create :set_default_status
16
18
  end
17
19
 
20
+ def set_default_status
21
+ self.status ||= 1
22
+ end
18
23
 
19
24
  def toggle_status!
20
25
  if active?
@@ -0,0 +1,12 @@
1
+ class Lca::Metadata < ActiveRecord::Base
2
+
3
+ belongs_to :model, polymorphic: true, required: true
4
+
5
+ def self.table_name
6
+ return "#{ ::LCA_OPTIONS[:table_name] }_metadata" if defined? ::LCA_OPTIONS
7
+ return "lca_models_metadata"
8
+ end
9
+
10
+ validates_presence_of :key
11
+
12
+ end
@@ -21,10 +21,13 @@ class Lca::Model < ActiveRecord::Base
21
21
  validates_presence_of :name, allow_blank: false
22
22
  validates_presence_of :path, allow_blank: false
23
23
 
24
+ has_many :metadata, class_name: "::Lca::Metadata", dependent: :destroy, as: :model
25
+
24
26
  before_validation :set_defaults
25
27
  def set_defaults
26
28
  self.path ||= name.delete(" ").gsub(/[^0-9a-z ]/i, '') if name
27
29
  self.path_slug = path.parameterize if path
30
+ self.metadata_inline ||= {}
28
31
  end
29
32
 
30
33
 
data/lib/lca/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lca
4
- VERSION = "0.2.4"
4
+ VERSION = "0.2.5"
5
5
  end
data/lib/lca.rb CHANGED
@@ -8,6 +8,7 @@ require "pg_ltree"
8
8
  require_relative "lca/version"
9
9
 
10
10
  require_relative "lca/models/concerns/statusable"
11
+ require_relative "lca/models/metadata"
11
12
  require_relative "lca/models/model"
12
13
  require_relative "lca/models/cycle"
13
14
  require_relative "lca/models/stage"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick @ Earthster
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-25 00:00:00.000000000 Z
11
+ date: 2021-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -118,6 +118,7 @@ files:
118
118
  - lib/lca/models/impact/human_health/cancer.rb
119
119
  - lib/lca/models/impact/technosphere.rb
120
120
  - lib/lca/models/impact/technosphere/resource_availability.rb
121
+ - lib/lca/models/metadata.rb
121
122
  - lib/lca/models/model.rb
122
123
  - lib/lca/models/process.rb
123
124
  - lib/lca/models/process/raw_resource.rb