Skip to content
This repository was archived by the owner on Dec 2, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions bin/console
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby

require "bundler/setup"
require "delta"
require 'bundler/setup'
require 'delta'

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
Expand All @@ -10,5 +10,5 @@ require "delta"
# require "pry"
# Pry.start

require "irb"
require 'irb'
IRB.start
33 changes: 16 additions & 17 deletions delta.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,36 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'delta/version'

Gem::Specification.new do |spec|
spec.name = "delta"
spec.name = 'delta'
spec.version = Delta::VERSION
spec.authors = ["Theodore Konukhov"]
spec.email = ["me@thdr.io"]
spec.authors = ['Theodore Konukhov']
spec.email = ['me@thdr.io']

spec.summary = %q{Deltas for ActiveRecord models}
spec.description = %q{Deltas for ActiveRecord models}
spec.homepage = "https://github.com/konukhov/delta"
spec.license = "MIT"
spec.homepage = 'https://github.com/konukhov/delta'
spec.license = 'MIT'

# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
# delete this section to allow pushing this gem to any host.
if spec.respond_to?(:metadata)
spec.metadata['allowed_push_host'] = "https://rubygems.org"
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
else
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
end

spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.bindir = "exe"
spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.require_paths = ['lib']

spec.add_runtime_dependency "request_store"
spec.add_runtime_dependency 'request_store'

spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "awesome_print"
spec.add_development_dependency "rails", "~> 4.2"
spec.add_development_dependency "rspec"
spec.add_development_dependency "rspec-rails"
spec.add_development_dependency "test_after_commit"
spec.add_development_dependency "pg"
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'awesome_print'
spec.add_development_dependency 'rails', '~> 5.0.2'
spec.add_development_dependency 'rspec'
spec.add_development_dependency 'rspec-rails'
spec.add_development_dependency 'pg'
#spec.add_development_dependency "rubocop"
end
12 changes: 6 additions & 6 deletions lib/delta.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ def configure
yield(config)
end

def current_user
current_user_proc && current_user_proc.call
def current_profile
current_profile_proc && current_profile_proc.call
end

def store
RequestStore
end

def set_current_user_proc(proc)
store[:current_user_proc] = proc
def set_current_profile_proc(proc)
store[:current_profile_proc] = proc
end

private

def current_user_proc
store[:current_user_proc]
def current_profile_proc
store[:current_profile_proc]
end
end

Expand Down
8 changes: 4 additions & 4 deletions lib/delta/adapters/active_record/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module Adapter
module ActiveRecord
module Ext
def self.included(base)
klass_name = "Delta::Adapter::ActiveRecord::Model"
_scope = -> { order('created_at').includes(:user) }
klass_name = 'Delta::Adapter::ActiveRecord::Model'
_scope = -> { order('created_at').includes(:profile) }

base.has_many :deltas, _scope,
class_name: klass_name,
Expand All @@ -13,12 +13,12 @@ def self.included(base)
end

class Model < ::ActiveRecord::Base
self.table_name = "deltas"
self.table_name = 'deltas'

scope :newest, -> { reorder('created_at desc') }

belongs_to :model, polymorphic: true
belongs_to :user
belongs_to :profile, polymorphic: true

def readonly?
persisted?
Expand Down
2 changes: 1 addition & 1 deletion lib/delta/adapters/active_record/store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def persist!
def attrs
@attrs ||= {
object: @changes,
user: Delta.current_user
profile: Delta.current_profile
}
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/delta/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ module Delta
class Config
attr_reader :adapters

attr_accessor :controller_user_method,
:user_model,
attr_accessor :controller_profile_method,
:profile_model,
:dont_use_after_commit_callbacks

def initialize
@adapters = Adapters.new(["active_record"])
@user_model = :user
@adapters = Adapters.new(%w[active_record])
@profile_model = :user
@dont_use_after_commit_callbacks = false
@controller_user_method = :current_user
@controller_profile_method = :current_user
end

def adapters=(adapter_names)
Expand Down
8 changes: 4 additions & 4 deletions lib/delta/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ module Controller
def self.included(base)
base.class_eval do
before_action do
Delta.set_current_user_proc ->{
Delta.set_current_profile_proc ->{
begin
self.send Delta.config.controller_user_method
self.send(Delta.config.controller_profile_method)
rescue => e
Rails.logger.info "[Delta] Unable to get current " +
"user (#{e.class}: #{e.message})"
Rails.logger.info '[Delta] Unable to get current ' +
"profile (#{e.class}: #{e.message})"
nil
end
}
Expand Down
6 changes: 3 additions & 3 deletions lib/delta/tracker/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def serialize(obj, action)
# And also think about tracking changes of polymorphic assocs.
def serialize_change(obj)
if (obj.changes.keys & @opts[:serialize]).any?
serialize(obj, "C")
serialize(obj, 'C')
end
end

Expand All @@ -64,7 +64,7 @@ def track_association_change!
after_update do
t = #{@trackable_class}.delta_tracker
delta = t.trackable_fields['#{@name}'].serialize_change(self)
model = association_cache['#{assoc}'] || send('#{assoc}')
model = send(:association_instance_get, '#{assoc}') || send('#{assoc}')

t.persist!(model, delta) if delta
end
Expand All @@ -82,7 +82,7 @@ def build_opts(opts)
[]
end

o[:only] = opts[:only] || ["add", "remove"]
o[:only] = opts[:only] || %w(add remove)
o[:notify] = opts[:notify] || false
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/delta/tracker/attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def serialize(model, action, opts = {})

{
name: @name,
action: "C",
action: 'C',
timestamp: opts[:timestamp] || Time.now.to_i,
object: changed.last
}
Expand Down
2 changes: 1 addition & 1 deletion lib/delta/tracker/belongs_to.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def track!
def serialize(model, action, opts = {})
return unless model.changes[key] || (polymorphic? && model.changes[type])

assoc = model.association_cache[@name] || model.send(@name)
assoc = model.send(:association_instance_get, @name) || model.send(@name)
key = @reflection.klass.primary_key
serialized = if assoc
{ key => assoc.send(key) }.tap do |hash|
Expand Down
2 changes: 1 addition & 1 deletion lib/delta/tracker/has_many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Delta
class Tracker
class HasMany < Association
def track!
actions = ["add", "remove"]
actions = %w(add remove)

if @opts[:only].is_a?(Array)
actions = @opts[:only].map(&:to_s) & actions
Expand Down
8 changes: 4 additions & 4 deletions lib/delta/tracker/model_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def cache_delta_fields!
.merge(delta_tracker.attributes)

fields.each do |name, field|
if serialized = field.serialize(self, "C", timestamp: ts)
if serialized = field.serialize(self, 'C', timestamp: ts)
deltas << serialized
end
end
Expand All @@ -66,15 +66,15 @@ def cache_delta_fields!

module DeltaAssociationsMethods
def delta_association_add(assoc_name, obj)
delta_association_invoke_action(assoc_name, obj, "A")
delta_association_invoke_action(assoc_name, obj, 'A')
end

def delta_association_remove(assoc_name, obj)
delta_association_invoke_action(assoc_name, obj, "R")
delta_association_invoke_action(assoc_name, obj, 'R')
end

def delta_association_change(assoc_name, obj)
delta_association_invoke_action(assoc_name, obj, "C")
delta_association_invoke_action(assoc_name, obj, 'C')
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/delta/tracking.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def track_deltas_on(field, field_opts = {})
private

def init_delta_tracker_if_needed(opts)
unless connection.table_exists?(table_name)
unless connection.data_source_exists?(table_name)
# TODO proper logging / errors
Rails.logger.warn("[Delta] `#{table_name}` doesn't exist: skipping initialization.")
return nil
Expand Down
2 changes: 1 addition & 1 deletion lib/delta/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Delta
VERSION = "0.0.1.alpha"
VERSION = '0.0.1.alpha'
end
4 changes: 2 additions & 2 deletions lib/generators/delta/create_table_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ module Generators
class CreateTableGenerator < Rails::Generators::Base
include Rails::Generators::Migration

source_root File.expand_path("../templates", __FILE__)
source_root File.expand_path('../templates', __FILE__)

def self.next_migration_number(dirname)
::ActiveRecord::Generators::Base.next_migration_number(dirname)
end

def copy_migration
migration_template "create_deltas.rb", "db/migrate/create_deltas.rb"
migration_template 'create_deltas.rb', 'db/migrate/create_deltas.rb'
end
end
end
Expand Down
5 changes: 4 additions & 1 deletion lib/generators/delta/templates/create_deltas.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ class CreateDeltas < ActiveRecord::Migration
def change
create_table :deltas, force: :cascade do |t|
# TODO: custom users key name
t.references :user, index: true
t.integer :profile_id
t.string :profile_type
t.references :model, index: true, polymorphic: true
t.json :object, null: false # TODO -> text if JSON is not supported

t.timestamp :created_at
end

add_index :deltas, %i[profile_id profile_type]
end
end
20 changes: 10 additions & 10 deletions spec/delta_spec.rb
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
require 'spec_helper'

describe Delta do
it "has config" do
it 'has config' do
expect(Delta.config).to be_instance_of(Delta::Config)
end

it "is configurable" do
it 'is configurable' do
Delta.configure do |c|
c.controller_user_method = :current_admin
c.controller_profile_method = :current_admin
end

expect(Delta.config.controller_user_method)
expect(Delta.config.controller_profile_method)
.to eq(:current_admin)

Delta.class_eval { @@config = Delta::Config.new }
end

it "current_user is thread-safe" do
it 'current_user is thread-safe' do
t1 = Thread.new do
Delta.set_current_user_proc ->{ :current_user_1 }
Delta.set_current_profile_proc ->{ :current_user_1 }
sleep 0.2
expect(Delta.current_user).to eq :current_user_1
expect(Delta.current_profile).to eq :current_user_1
end

t2 = Thread.new do
sleep 0.1
Delta.set_current_user_proc ->{ :current_user_2 }
expect(Delta.current_user).to eq :current_user_2
Delta.set_current_profile_proc ->{ :current_user_2 }
expect(Delta.current_profile).to eq :current_user_2
end

[t1, t2].map &:join

expect(Delta.current_user).to eq nil
expect(Delta.current_profile).to eq nil
end
end
Loading