has_changelogs 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1869edef6186e5ad2e9cd9c9b22270005cff43e0
4
+ data.tar.gz: f4c0e30bc0ec59be808b12bb64410f61bcc9e4f5
5
+ SHA512:
6
+ metadata.gz: 05d3d5ec172f9268bc21e23d1e6f825b27ea73651de45d9bdd2d47a72096158d60b9185152f1ca62b183606b583606501581ae38f323425ffe979d97003c9073
7
+ data.tar.gz: e43ec882886adfaf94d50f8d196066d838d60528c9f03b27533865db757a411a48b9d4afd3a38ef26cb2e7ca81d33322d1da15a79f5bb0718b45ed0dd24b3ba9
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /spec/.DS_Store
11
+ /spec/has_changelogs.sqlite3
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in has_changelogs.gemspec
4
+ gemspec
5
+
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # HasChangelogs
2
+
3
+ has_changelogs tracks changes on a model and it's associations for applications that need to have change history. The version is however, 0.1.0, so use at your own perril.
4
+
5
+ Especially a generator for the changelog model is missing - see /spec/fixtures/active_record/changelog.rb for it.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'has_changelogs'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install has_changelogs
22
+
23
+ ## Usage
24
+
25
+ Given you had a fitting Changelog Model (see ./spec/fixtures/active_record/changelog.rb) you can do the following:
26
+
27
+ ```ruby
28
+ class User < ActiveRecord::Base
29
+ has_changelogs
30
+
31
+ def my_condition
32
+ name == "True Condition"
33
+ end
34
+ end
35
+
36
+ class LogEverythingUser < User
37
+ has_changelogs ignore: [:type, :id]
38
+ end
39
+
40
+ class OnlyName < User
41
+ has_changelogs only: :name
42
+ end
43
+
44
+ class IgnoreName < User
45
+ has_changelogs ignore: :name
46
+ end
47
+
48
+ class IfCondition < User
49
+ has_changelogs if: :my_condition
50
+ end
51
+
52
+ class UnlessCondition < User
53
+ has_changelogs unless: :my_condition
54
+ end
55
+
56
+ class WithPassportsUser < LogEverythingUser
57
+ has_many :passports, foreign_key: :user_id
58
+ end
59
+
60
+ class Passport < ActiveRecord::Base
61
+ belongs_to :user, class_name: "WithPassportsUser"
62
+ has_changelogs at: :user
63
+ end
64
+
65
+ ```
66
+
67
+ ## Development
68
+
69
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
70
+
71
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
72
+
73
+ ## Contributing
74
+
75
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bitcrowd/has_changelogs.
76
+
77
+
78
+ ## License
79
+
80
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
81
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "has_changelogs"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'has_changelogs/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'has_changelogs'
8
+ spec.version = HasChangelogs::VERSION
9
+ spec.authors = ['Elizabeth Brae', 'Christoph Beck']
10
+ spec.email = ["info@bitcrowd.net"]
11
+
12
+ spec.summary = %q{has_changelogs tracks changes on a model and it's associations for applications that need to have change history.}
13
+ spec.description = %q{has_changelogs tracks changes on a model and it's associations for applications that need to have change history. This is not about versioning your model, and the version is however, 0.1.0, so use at your own perril. The changelogs contain a JSON representation of the changes.}
14
+ spec.homepage = "https://github.com/bitcrowd/has_changelogs"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_dependency "activesupport"
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.10"
31
+ spec.add_development_dependency "sqlite3"
32
+ spec.add_development_dependency "activerecord"
33
+
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "rspec"
36
+ spec.add_development_dependency "pry"
37
+
38
+ end
@@ -0,0 +1,3 @@
1
+ module HasChangelogs
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,173 @@
1
+ require 'active_record'
2
+ require 'has_changelogs/version'
3
+
4
+ module HasChangelogs
5
+ module ClassMethods
6
+
7
+ def has_changelogs(options = {})
8
+ send :include, InstanceMethods
9
+
10
+ after_create :record_created if !options[:on] || options[:on].include?(:create)
11
+ before_destroy :record_will_be_destroyed if !options[:on] || options[:on].include?(:destroy)
12
+
13
+ after_update :record_updated, :if => :change_relevant? if !options[:on] || options[:on].include?(:update)
14
+
15
+ prepare_class_options(options)
16
+
17
+ has_many :changelogs, as: :logable
18
+ end
19
+
20
+ private
21
+
22
+ def prepare_class_options(options)
23
+ class_attribute :has_changelog_options
24
+ self.has_changelog_options = options.dup
25
+
26
+ has_changelog_options[:ignore] = (Array(has_changelog_options[:ignore]) | [:updated_at, :created_at, :id] ).map &:to_s
27
+ has_changelog_options[:only] = Array(has_changelog_options[:only]).map &:to_s
28
+ has_changelog_options[:force] = Array(has_changelog_options[:force]).map &:to_s
29
+ end
30
+
31
+ end
32
+
33
+ module InstanceMethods
34
+
35
+ def change_relevant?
36
+ if_condition = self.class.has_changelog_options[:if]
37
+ unless_condition = self.class.has_changelog_options[:unless]
38
+
39
+ conditions_met?(if_condition, unless_condition) && object_changed_notably?
40
+ end
41
+
42
+ def conditions_met?(if_condition, unless_condition)
43
+ (if_condition.blank? || if_condition.call(self)) &&
44
+ (unless_condition.blank? || !unless_condition.call(self))
45
+ end
46
+
47
+ def notable_changes
48
+ notable_attributes
49
+ end
50
+
51
+ def notable_attributes
52
+ only = self.class.has_changelog_options[:only]
53
+ force = self.class.has_changelog_options[:force]
54
+ notable = only.empty? ? changed_and_not_ignored : (changed_and_not_ignored & only)
55
+ notable + force
56
+ end
57
+
58
+ def changed_and_not_ignored
59
+ ignore = self.class.has_changelog_options[:ignore]
60
+ changed - ignore
61
+ end
62
+
63
+ def object_changed_notably?
64
+ notable_changes.any?
65
+ end
66
+ # the actions
67
+
68
+ def record_created
69
+ log_change(log_scope: log_scope, log_action: 'created', changed_data: log_data, log_origin: log_origin)
70
+ end
71
+
72
+ def record_updated
73
+ log_change(log_scope: log_scope, log_action: 'updated', changed_data: log_data, log_origin: log_origin)
74
+ end
75
+
76
+ def record_will_be_destroyed
77
+ log_change(log_scope: log_scope, log_action: 'destroyed', changed_data: self.attributes, log_origin: log_origin)
78
+ end
79
+
80
+ def log_change(options = {})
81
+ changelog_association.create(options)
82
+ end
83
+
84
+ def log_scope
85
+ has_changelog_options[:at].present? ? :association : :instance
86
+ end
87
+
88
+ def logged_model
89
+ has_changelog_options[:at].present? ?
90
+ send(has_changelog_options[:at]) : self
91
+ end
92
+
93
+ def log_origin
94
+ self.class.to_s
95
+ end
96
+
97
+ def changelog_association
98
+ logged_model.send changelog_association_name
99
+ end
100
+
101
+ def changelog_association_name
102
+ self.class.has_changelog_options[:changelogs_association] || :changelogs
103
+ end
104
+
105
+ def log_data(options = {})
106
+ raw_changed_data(options).select do |key, value|
107
+ notable_changes.include? key.to_s
108
+ end
109
+ end
110
+
111
+ def raw_changed_data(options = {})
112
+ options[:change_data] || self.changes || {}
113
+ end
114
+
115
+ # def epic_hero!(options = {})
116
+ # options[:epic_hero]
117
+ # end
118
+
119
+ # def epic_action!(options = {})
120
+ # options[:epic_action] || "updated"
121
+ # end
122
+
123
+ # def epic_action_by_admin!(options = {})
124
+ # !!options[:epic_action_by_admin]
125
+ # end
126
+
127
+ # def log_item(options = {})
128
+ # options[:log_item] || self
129
+ # end
130
+
131
+ # def epic_item_nickname!(options = {})
132
+ # options[:log_item_nickname]
133
+ # end
134
+
135
+ # def epic_item_owner!(options = {})
136
+ # options[:log_item_owner]
137
+ # end
138
+
139
+
140
+ # def epic_treasure!(options = {})
141
+ # options[:epic_treasure]
142
+ # end
143
+ # def epic_treasure_nickname!(options = {})
144
+ # options[:epic_treasure_nickname]
145
+ # end
146
+ # def epic_treasureguard!(options = {})
147
+ # options[:epic_treasureguard]
148
+ # end
149
+
150
+ # def epic_change_data!(options = {})
151
+ # raw_change_data.to_json
152
+ # end
153
+
154
+ # def epic_change_attributes!(options = {})
155
+ # options[:epic_change_attributes] || raw_change_data(options).keys.join(",")
156
+ # end
157
+
158
+ # private
159
+
160
+ # def raw_change_data(options = {})
161
+ # options[:epic_change_data] || self.changes || {}
162
+ # end
163
+
164
+ end
165
+
166
+ def self.included(receiver)
167
+ receiver.extend ClassMethods
168
+ end
169
+ end
170
+
171
+ ActiveSupport.on_load(:active_record) do
172
+ include HasChangelogs
173
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: has_changelogs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Elizabeth Brae
8
+ - Christoph Beck
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-10-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.10'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.10'
42
+ - !ruby/object:Gem::Dependency
43
+ name: sqlite3
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: activerecord
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '10.0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '10.0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: pry
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: has_changelogs tracks changes on a model and it's associations for applications
113
+ that need to have change history. This is not about versioning your model, and the
114
+ version is however, 0.1.0, so use at your own perril. The changelogs contain a JSON
115
+ representation of the changes.
116
+ email:
117
+ - info@bitcrowd.net
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - ".gitignore"
123
+ - ".rspec"
124
+ - ".travis.yml"
125
+ - Gemfile
126
+ - LICENSE.txt
127
+ - README.md
128
+ - Rakefile
129
+ - bin/console
130
+ - bin/setup
131
+ - has_changelogs.gemspec
132
+ - lib/has_changelogs.rb
133
+ - lib/has_changelogs/version.rb
134
+ homepage: https://github.com/bitcrowd/has_changelogs
135
+ licenses:
136
+ - MIT
137
+ metadata:
138
+ allowed_push_host: https://rubygems.org
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.4.5.1
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: has_changelogs tracks changes on a model and it's associations for applications
159
+ that need to have change history.
160
+ test_files: []