record_with_operator 0.1.0 → 1.0.0
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.
- data/README.rdoc +58 -24
- data/Rakefile +10 -10
- data/lib/record_with_operator/operator.rb +11 -0
- data/lib/record_with_operator/recorder.rb +58 -0
- data/lib/record_with_operator/version.rb +1 -1
- data/lib/record_with_operator.rb +34 -5
- data/record_with_operator.gemspec +1 -1
- data/test/record_with_operator_belongs_to_association_test.rb +13 -5
- data/test/record_with_operator_has_many_dependent_test.rb +2 -2
- data/test/record_with_operator_has_one_association_test.rb +15 -6
- data/test/record_with_operator_reflection_test.rb +5 -1
- data/test/record_with_operator_test.rb +44 -19
- data/test/record_with_operator_user_class_name_test.rb +8 -3
- metadata +9 -13
- data/lib/record_with_operator/associations/extension.rb +0 -24
- data/lib/record_with_operator/extension.rb +0 -146
- data/lib/record_with_operator/relation_methods.rb +0 -66
- data/lib/record_with_operator/utility.rb +0 -19
data/README.rdoc
CHANGED
@@ -2,66 +2,96 @@
|
|
2
2
|
|
3
3
|
== Introduction
|
4
4
|
|
5
|
-
RecordWithOperator is a
|
6
|
-
Also it makes creator, updater, deleter association (belongs_to)
|
5
|
+
RecordWithOperator is a gem that makes your active record models to be saved or logically deleted with created_by, updated_by, deleted_by (column names can be changed).
|
6
|
+
Also it makes creator, updater, deleter association (belongs_to).
|
7
7
|
|
8
|
-
You
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
You can specify which action you want to save operator like this.
|
9
|
+
|
10
|
+
records_with_oprator_on :cerate, :update, destroy
|
11
|
+
|
12
|
+
RecordWithOperator needs to know who is currently operating.
|
13
|
+
For that, you need to set operator through one of the following ways.
|
14
|
+
|
15
|
+
# Every ActiveRecord object has operator= and operator.
|
16
|
+
record.operator = current_user
|
17
|
+
record.save
|
18
|
+
|
19
|
+
# RecordWithOperator module has operator= and operator.
|
20
|
+
RecordWithOperator.operator = current_user
|
21
|
+
obj = YourModel.find(id)
|
22
|
+
obj.attributes = some_params
|
23
|
+
obj.save
|
24
|
+
|
25
|
+
In rails application, a nice place for setting operator whould be in filters.
|
26
|
+
|
27
|
+
Operators whould be also useful for your access control features on model's side.
|
13
28
|
|
14
29
|
The logical deletion function itself is out of this plugin's scope.
|
15
30
|
This plugin assumes that the logical deletion is kicked by record.destory.
|
16
31
|
|
17
|
-
==
|
32
|
+
== API Changes
|
33
|
+
|
34
|
+
:for option in find method has been removed.
|
35
|
+
(It's no use since operator is now global.)
|
36
|
+
Please set operator before search if you need operator at that timing.
|
18
37
|
|
19
|
-
|
38
|
+
Also, operator_stamps is removed.
|
20
39
|
|
21
|
-
|
40
|
+
== Installation
|
22
41
|
|
23
|
-
## Gemfile
|
42
|
+
## Gemfile
|
24
43
|
gem 'record_with_operator'
|
25
44
|
|
26
45
|
== Example
|
27
46
|
|
28
47
|
Create Note table with nessisary attributes:
|
29
48
|
class CreateNotes < ActiveRecord::Migration
|
30
|
-
def
|
49
|
+
def change
|
31
50
|
create_table :users do |t|
|
32
51
|
t.string :body
|
33
|
-
t.
|
52
|
+
t.integer :created_by
|
53
|
+
t.integer :updated_by
|
54
|
+
t.integer :deleted_by
|
55
|
+
|
56
|
+
t.boolean :deleted
|
57
|
+
|
34
58
|
t.timestamps
|
35
59
|
end
|
36
60
|
end
|
37
61
|
|
62
|
+
Set an operator in some filter
|
63
|
+
|
64
|
+
def set_operator
|
65
|
+
RecordWithOperator.operator = current_user
|
66
|
+
end
|
38
67
|
|
39
|
-
Create a new note object
|
68
|
+
Create a new note object:
|
40
69
|
|
41
|
-
note = Note.create(:body => "This is my first note."
|
70
|
+
note = Note.create(:body => "This is my first note.")
|
42
71
|
# note.operator will be current_user
|
43
72
|
# note.created_by will be current_user.id
|
44
73
|
|
45
|
-
Get note objects
|
74
|
+
Get note objects:
|
46
75
|
|
47
|
-
notes = Note.
|
76
|
+
notes = Note.all
|
48
77
|
# notes.first.operator will be current_user
|
49
|
-
# notes.find_by_body("This is my first note.").operator will be current_user
|
50
78
|
|
51
79
|
Create note's comments:
|
52
80
|
|
53
|
-
note = Note.find(params[:id]
|
81
|
+
note = Note.find(params[:id])
|
54
82
|
note.comments.create!(:body => params[:comment_body])
|
55
|
-
# comment
|
83
|
+
# comment.operator will be current_user
|
84
|
+
# comment.created_by will be current_user.id
|
56
85
|
|
57
86
|
== Configuration
|
58
87
|
|
59
|
-
You can change the operator's class name by setting RecordWithOperator.config[:
|
88
|
+
You can change the operator's class name by setting RecordWithOperator.config[:operator_class_name]. (It was renamed from :user_class_name. )
|
60
89
|
The default is 'User'.
|
61
|
-
|
90
|
+
|
91
|
+
Note that it is required to change this value before your model classes are loaded.
|
62
92
|
For example, you can write the code under config/initializers.
|
63
93
|
|
64
|
-
RecordWithOperator.config[:
|
94
|
+
RecordWithOperator.config[:operator_class_name] = "AdminUser"
|
65
95
|
|
66
96
|
It's also possible to modify options for creator/updater/deleter associations.
|
67
97
|
For example, in the case you use acts_as_paranoid and want to get creator/updater/deleter even if they are deleted,
|
@@ -69,4 +99,8 @@ the configuration will be look like this.
|
|
69
99
|
|
70
100
|
RecordWithOperator.config[:operator_association_options] = {:with_deleted => true}
|
71
101
|
|
72
|
-
|
102
|
+
You can cange created_by, updated_by, deleted_by column name by changing RecordWithOperator.config with keys :creator_column, :updater_column and :deleter_column.
|
103
|
+
|
104
|
+
The association names (such as creator, updater and deleter) can not be changed in this version.
|
105
|
+
|
106
|
+
Copyright (c) 2009-2013 Yasuko Ohba, released under the MIT license
|
data/Rakefile
CHANGED
@@ -2,8 +2,8 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'rake/clean'
|
4
4
|
require 'rake/testtask'
|
5
|
-
require '
|
6
|
-
require 'rake/gempackagetask'
|
5
|
+
#require 'rdoc/task'
|
6
|
+
#require 'rake/gempackagetask'
|
7
7
|
|
8
8
|
desc 'Default: run unit tests.'
|
9
9
|
task :default => :test
|
@@ -16,11 +16,11 @@ Rake::TestTask.new(:test) do |t|
|
|
16
16
|
t.verbose = true
|
17
17
|
end
|
18
18
|
|
19
|
-
desc 'Generate documentation for the record_with_operator plugin.'
|
20
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
21
|
-
rdoc.rdoc_dir = 'rdoc'
|
22
|
-
rdoc.title = 'RecordWithOperator'
|
23
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
24
|
-
rdoc.rdoc_files.include('README.rdoc')
|
25
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
26
|
-
end
|
19
|
+
#desc 'Generate documentation for the record_with_operator plugin.'
|
20
|
+
#Rake::RDocTask.new(:rdoc) do |rdoc|
|
21
|
+
# rdoc.rdoc_dir = 'rdoc'
|
22
|
+
# rdoc.title = 'RecordWithOperator'
|
23
|
+
# rdoc.options << '--line-numbers' << '--inline-source'
|
24
|
+
# rdoc.rdoc_files.include('README.rdoc')
|
25
|
+
# rdoc.rdoc_files.include('lib/**/*.rb')
|
26
|
+
#end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module RecordWithOperator
|
2
|
+
module Recorder
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def set_creator
|
10
|
+
send("#{RecordWithOperator.creator_column}=", operator.try(:id))
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_updater
|
14
|
+
return unless changed? # no use setting updating_by when it's not changed
|
15
|
+
return unless operator # avoid changing value to be nil
|
16
|
+
send("#{RecordWithOperator.updater_column}=", operator.id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_deleter
|
20
|
+
return if frozen?
|
21
|
+
return unless operator
|
22
|
+
self.class.update_all("#{RecordWithOperator.deleter_column} = #{operator.id}", ["#{self.class.primary_key} = ?", id])
|
23
|
+
send("#{RecordWithOperator.deleter_column}=", operator.id)
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
VALID_ACTIONS = %w(create update destroy)
|
28
|
+
|
29
|
+
def records_with_operator_on(*args)
|
30
|
+
raise "valid actions are #{VALID_ACTIONS.inspect}." unless args.all?{|arg| VALID_ACTIONS.include?(arg.to_s) }
|
31
|
+
|
32
|
+
@records_on = args.map(&:to_s)
|
33
|
+
|
34
|
+
before_create :set_creator if records_creator?
|
35
|
+
before_save :set_updater if records_updater?
|
36
|
+
before_destroy :update_deleter if records_deleter?
|
37
|
+
|
38
|
+
if self.table_exists?
|
39
|
+
belongs_to :creator, {:foreign_key => "created_by", :class_name => RecordWithOperator.config[:operator_class_name]}.merge(RecordWithOperator.config[:operator_association_options]) if records_creator?
|
40
|
+
belongs_to :updater, {:foreign_key => "updated_by", :class_name => RecordWithOperator.config[:operator_class_name]}.merge(RecordWithOperator.config[:operator_association_options]) if records_updater?
|
41
|
+
belongs_to :deleter, {:foreign_key => "deleted_by", :class_name => RecordWithOperator.config[:operator_class_name]}.merge(RecordWithOperator.config[:operator_association_options]) if records_deleter?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def records_creator?
|
46
|
+
@records_on.include?("create")
|
47
|
+
end
|
48
|
+
|
49
|
+
def records_updater?
|
50
|
+
@records_on.include?("update")
|
51
|
+
end
|
52
|
+
|
53
|
+
def records_deleter?
|
54
|
+
@records_on.include?("destroy")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/record_with_operator.rb
CHANGED
@@ -1,6 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module RecordWithOperator
|
2
|
+
def self.config
|
3
|
+
@config ||= {
|
4
|
+
:operator_class_name => "User",
|
5
|
+
:creator_column => "created_by",
|
6
|
+
:updater_column => "updated_by",
|
7
|
+
:deleter_column => "deleted_by",
|
8
|
+
:operator_association_options => {}}
|
9
|
+
@config
|
10
|
+
end
|
4
11
|
|
5
|
-
|
6
|
-
|
12
|
+
def self.operator_class_name
|
13
|
+
config[:operator_class_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.creator_column
|
17
|
+
config[:creator_column]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.updater_column
|
21
|
+
config[:updater_column]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.deleter_column
|
25
|
+
config[:deleter_column]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
require 'record_with_operator/operator'
|
30
|
+
require 'record_with_operator/recorder'
|
31
|
+
|
32
|
+
RecordWithOperator.send :extend, RecordWithOperator::Operator
|
33
|
+
|
34
|
+
ActiveRecord::Base.send :include, RecordWithOperator::Operator
|
35
|
+
ActiveRecord::Base.send :include, RecordWithOperator::Recorder
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
s.licenses = ["MIT"]
|
24
24
|
|
25
|
-
s.add_dependency 'activerecord'
|
25
|
+
s.add_dependency 'activerecord'
|
26
26
|
s.add_development_dependency 'bundler', ['>= 1.0.0']
|
27
27
|
s.add_development_dependency 'rake', ['>= 0.8.7']
|
28
28
|
s.add_development_dependency 'sqlite3', ['>= 0']
|
@@ -6,15 +6,19 @@ end
|
|
6
6
|
class NoteBelongsToMemo < ActiveRecord::Base
|
7
7
|
set_table_name "notes"
|
8
8
|
belongs_to :memo
|
9
|
+
|
10
|
+
records_with_operator_on :create, :update, :destroy
|
9
11
|
end
|
10
12
|
|
11
13
|
class Memo < ActiveRecord::Base
|
12
14
|
set_table_name "memos"
|
15
|
+
|
16
|
+
records_with_operator_on :create, :update, :destroy
|
13
17
|
end
|
14
18
|
|
15
19
|
class RecordWithOperatorBelongsTo < ActiveSupport::TestCase
|
16
20
|
def setup
|
17
|
-
RecordWithOperator.config[:
|
21
|
+
RecordWithOperator.config[:operator_class_name] = "User"
|
18
22
|
@user1 = User.create!(:name => "user1")
|
19
23
|
@user2 = User.create!(:name => "user2")
|
20
24
|
@note_created_by_user1 = NoteBelongsToMemo.create!(:body => "test", :operator => @user1)
|
@@ -23,14 +27,16 @@ class RecordWithOperatorBelongsTo < ActiveSupport::TestCase
|
|
23
27
|
# belongs_to Association Test
|
24
28
|
# build_association
|
25
29
|
def test_build_memo_should_have_operator
|
26
|
-
|
30
|
+
RecordWithOperator.operator = @user2
|
31
|
+
note = NoteBelongsToMemo.find(@note_created_by_user1.id)
|
27
32
|
memo = note.build_memo(:body => "memo")
|
28
33
|
assert_equal @user2, memo.operator
|
29
34
|
end
|
30
35
|
|
31
36
|
# create_association
|
32
37
|
def test_create_memo_should_have_operator_and_created_by
|
33
|
-
|
38
|
+
RecordWithOperator.operator = @user2
|
39
|
+
note = NoteBelongsToMemo.find(@note_created_by_user1.id)
|
34
40
|
memo = note.create_memo(:body => "memo")
|
35
41
|
assert_equal false, memo.new_record?
|
36
42
|
assert_equal @user2, memo.operator
|
@@ -39,7 +45,8 @@ class RecordWithOperatorBelongsTo < ActiveSupport::TestCase
|
|
39
45
|
|
40
46
|
# association=
|
41
47
|
def test_memo_eql_should_have_operator_and_created_by
|
42
|
-
|
48
|
+
RecordWithOperator.operator = @user2
|
49
|
+
note = NoteBelongsToMemo.find(@note_created_by_user1.id)
|
43
50
|
memo = Memo.new(:body => "memo")
|
44
51
|
note.memo = memo # not save
|
45
52
|
assert_equal @user2, memo.operator
|
@@ -47,7 +54,8 @@ class RecordWithOperatorBelongsTo < ActiveSupport::TestCase
|
|
47
54
|
|
48
55
|
# association
|
49
56
|
def test_auto_found_memo_should_have_operator
|
50
|
-
|
57
|
+
RecordWithOperator.operator = @user2
|
58
|
+
note = NoteBelongsToMemo.find(@note_created_by_user1.id)
|
51
59
|
note.create_memo(:body => "memo")
|
52
60
|
assert_equal @user2, note.memo(true).operator
|
53
61
|
end
|
@@ -5,7 +5,7 @@ end
|
|
5
5
|
|
6
6
|
class NoteWithUserWithDependency < ActiveRecord::Base
|
7
7
|
set_table_name "notes"
|
8
|
-
has_many :memos, :class_name => "
|
8
|
+
has_many :memos, :class_name => "MemoWithUserWithDependency", :foreign_key => "note_id", :dependent => :destroy
|
9
9
|
|
10
10
|
before_destroy :check_operator
|
11
11
|
|
@@ -29,7 +29,7 @@ end
|
|
29
29
|
|
30
30
|
class RecordWithOperatorHasManyDependentTest < ActiveSupport::TestCase
|
31
31
|
def setup
|
32
|
-
RecordWithOperator.config[:
|
32
|
+
RecordWithOperator.config[:operator_class_name] = "User"
|
33
33
|
@user1 = User.create!(:name => "user1")
|
34
34
|
raise "@user1.id is nil" unless @user1.id
|
35
35
|
@user2 = User.create!(:name => "user2")
|
@@ -6,31 +6,38 @@ end
|
|
6
6
|
class NoteHasOneMemo < ActiveRecord::Base
|
7
7
|
set_table_name "notes"
|
8
8
|
has_one :memo, :class_name => "Memo", :foreign_key => "note_id"
|
9
|
+
|
10
|
+
records_with_operator_on :create, :update, :destroy
|
9
11
|
end
|
10
12
|
|
11
13
|
class Memo < ActiveRecord::Base
|
12
14
|
set_table_name "memos"
|
15
|
+
|
16
|
+
records_with_operator_on :create, :update, :destroy
|
13
17
|
end
|
14
18
|
|
15
19
|
class RecordWithOperatorHasOneAssociationTest < ActiveSupport::TestCase
|
16
20
|
def setup
|
17
|
-
RecordWithOperator.config[:
|
21
|
+
RecordWithOperator.config[:operator_class_name] = "User"
|
18
22
|
@user1 = User.create!(:name => "user1")
|
19
23
|
@user2 = User.create!(:name => "user2")
|
20
|
-
|
24
|
+
RecordWithOperator.operator = @user1
|
25
|
+
@note_created_by_user1 = NoteHasOneMemo.create!(:body => "test")
|
21
26
|
end
|
22
27
|
|
23
28
|
# has_one Association Test
|
24
29
|
# build_association
|
25
30
|
def test_build_memo_should_have_operator
|
26
|
-
|
31
|
+
RecordWithOperator.operator = @user2
|
32
|
+
note = NoteHasOneMemo.find(@note_created_by_user1.id)
|
27
33
|
memo = note.build_memo(:body => "memo")
|
28
34
|
assert_equal @user2, memo.operator
|
29
35
|
end
|
30
36
|
|
31
37
|
# create_association
|
32
38
|
def test_create_memo_should_have_operator_and_created_by
|
33
|
-
|
39
|
+
RecordWithOperator.operator = @user2
|
40
|
+
note = NoteHasOneMemo.find(@note_created_by_user1.id)
|
34
41
|
memo = note.create_memo(:body => "memo")
|
35
42
|
assert_equal false, memo.new_record?
|
36
43
|
assert_equal @user2, memo.operator
|
@@ -39,7 +46,8 @@ class RecordWithOperatorHasOneAssociationTest < ActiveSupport::TestCase
|
|
39
46
|
|
40
47
|
# association=
|
41
48
|
def test_memo_eql_should_have_operator_and_created_by
|
42
|
-
|
49
|
+
RecordWithOperator.operator = @user2
|
50
|
+
note = NoteHasOneMemo.find(@note_created_by_user1.id)
|
43
51
|
memo = Memo.new(:body => "memo")
|
44
52
|
note.memo = memo
|
45
53
|
assert_equal false, memo.new_record?
|
@@ -49,7 +57,8 @@ class RecordWithOperatorHasOneAssociationTest < ActiveSupport::TestCase
|
|
49
57
|
|
50
58
|
# association
|
51
59
|
def test_auto_found_memo_should_have_operator
|
52
|
-
|
60
|
+
RecordWithOperator.operator = @user2
|
61
|
+
note = NoteHasOneMemo.find(@note_created_by_user1.id)
|
53
62
|
note.create_memo(:body => "memo")
|
54
63
|
assert_equal @user2, note.memo(true).operator
|
55
64
|
end
|
@@ -5,15 +5,19 @@ end
|
|
5
5
|
|
6
6
|
class NoteForReflectionTest < ActiveRecord::Base
|
7
7
|
set_table_name "notes"
|
8
|
+
|
9
|
+
records_with_operator_on :create, :update, :destroy
|
8
10
|
end
|
9
11
|
|
10
12
|
class CreatorNoteForReflectionTest < ActiveRecord::Base
|
11
13
|
set_table_name "creator_notes"
|
14
|
+
|
15
|
+
records_with_operator_on :create
|
12
16
|
end
|
13
17
|
|
14
18
|
class RecordWithOperatorReflectionTest < ActiveSupport::TestCase
|
15
19
|
def setup
|
16
|
-
RecordWithOperator.config[:
|
20
|
+
RecordWithOperator.config[:operator_class_name] = "User"
|
17
21
|
@user1 = User.create!(:name => "user1")
|
18
22
|
raise "@user1.id is nil" unless @user1.id
|
19
23
|
@note = NoteForReflectionTest.create!(:body => "test", :operator => @user1)
|
@@ -11,6 +11,8 @@ class NoteWithUser < ActiveRecord::Base
|
|
11
11
|
|
12
12
|
alias_method :destroy!, :destroy
|
13
13
|
|
14
|
+
records_with_operator_on :create, :update, :destroy
|
15
|
+
|
14
16
|
def destroy
|
15
17
|
with_transaction_returning_status do
|
16
18
|
_run_destroy_callbacks do
|
@@ -33,21 +35,26 @@ class MemoWithUser < ActiveRecord::Base
|
|
33
35
|
set_table_name "memos"
|
34
36
|
|
35
37
|
scope :new_arrivals, {:order => "updated_at desc"}
|
38
|
+
|
39
|
+
records_with_operator_on :create, :update, :destroy
|
36
40
|
end
|
37
41
|
|
38
42
|
class UpdaterNoteWithUser < ActiveRecord::Base
|
39
43
|
set_table_name "updater_notes"
|
40
44
|
|
45
|
+
records_with_operator_on :update
|
41
46
|
end
|
42
47
|
|
43
48
|
class DeleterNoteWithUser < ActiveRecord::Base
|
44
49
|
set_table_name "deleter_notes"
|
45
50
|
|
51
|
+
records_with_operator_on :destroy
|
52
|
+
|
46
53
|
end
|
47
54
|
|
48
55
|
class RecordWithOperatorTest < ActiveSupport::TestCase
|
49
56
|
def setup
|
50
|
-
RecordWithOperator.config[:
|
57
|
+
RecordWithOperator.config[:operator_class_name] = "User"
|
51
58
|
@user1 = User.create!(:name => "user1")
|
52
59
|
raise "@user1.id is nil" unless @user1.id
|
53
60
|
@user2 = User.create!(:name => "user2")
|
@@ -104,12 +111,14 @@ class RecordWithOperatorTest < ActiveSupport::TestCase
|
|
104
111
|
|
105
112
|
# find with :for
|
106
113
|
def test_note_should_be_found_with_for
|
107
|
-
|
114
|
+
RecordWithOperator.operator = @user2
|
115
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
108
116
|
assert_equal(@user2, note.operator)
|
109
117
|
end
|
110
118
|
|
111
119
|
def test_note_should_be_found_with_for_through_named_scope
|
112
|
-
|
120
|
+
RecordWithOperator.operator = @user2
|
121
|
+
note = NoteWithUser.new_arrivals.find(@note_created_by_user1.id)
|
113
122
|
assert_equal(@user2, note.operator)
|
114
123
|
end
|
115
124
|
|
@@ -130,7 +139,8 @@ class RecordWithOperatorTest < ActiveSupport::TestCase
|
|
130
139
|
end
|
131
140
|
|
132
141
|
def test_note_should_be_updated_with_updated_by
|
133
|
-
|
142
|
+
RecordWithOperator.operator = @user2
|
143
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
134
144
|
note.body = "changed"
|
135
145
|
note.save!
|
136
146
|
assert_equal(@user2.id, note.updated_by)
|
@@ -139,7 +149,8 @@ class RecordWithOperatorTest < ActiveSupport::TestCase
|
|
139
149
|
end
|
140
150
|
|
141
151
|
def test_note_should_be_destroyed_with_deleted_by
|
142
|
-
|
152
|
+
RecordWithOperator.operator = @user2
|
153
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
143
154
|
note.destroy # logically
|
144
155
|
note = NoteWithUser.find(@note_created_by_user1.id)
|
145
156
|
raise "not deleted" unless note.deleted?
|
@@ -155,7 +166,8 @@ class RecordWithOperatorTest < ActiveSupport::TestCase
|
|
155
166
|
|
156
167
|
# has_many Association Test
|
157
168
|
def test_builded_memo_should_have_operator
|
158
|
-
|
169
|
+
RecordWithOperator.operator = @user2
|
170
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
159
171
|
memo = note.memos.build(:body => "memo")
|
160
172
|
assert_equal @user2, memo.operator
|
161
173
|
end
|
@@ -168,7 +180,8 @@ class RecordWithOperatorTest < ActiveSupport::TestCase
|
|
168
180
|
|
169
181
|
|
170
182
|
def test_created_memo_should_have_operator_and_created_by
|
171
|
-
|
183
|
+
RecordWithOperator.operator = @user2
|
184
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
172
185
|
memo = note.memos.create(:body => "memo")
|
173
186
|
assert_equal false, memo.new_record?
|
174
187
|
assert_equal @user2, memo.operator
|
@@ -176,70 +189,82 @@ class RecordWithOperatorTest < ActiveSupport::TestCase
|
|
176
189
|
end
|
177
190
|
|
178
191
|
def test_auto_found_memo_should_have_operator
|
179
|
-
|
192
|
+
RecordWithOperator.operator = @user2
|
193
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
180
194
|
note.memos.create!(:body => "memo")
|
181
195
|
assert_equal @user2, note.memos(true).first.operator
|
182
196
|
end
|
183
197
|
|
184
198
|
def test_manualy_found_memo_should_have_operator
|
185
|
-
|
199
|
+
RecordWithOperator.operator = @user2
|
200
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
186
201
|
note.memos.create!(:body => "memo")
|
187
202
|
assert_equal @user2, note.memos.find(:first).operator
|
188
203
|
end
|
189
204
|
|
190
205
|
def test_dynamically_found_memo_should_have_operator
|
191
|
-
|
206
|
+
RecordWithOperator.operator = @user2
|
207
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
192
208
|
note.memos.create!(:body => "memo")
|
193
209
|
assert_equal @user2, note.memos.find_by_body("memo").operator
|
194
210
|
end
|
195
211
|
|
196
212
|
def test_dynamically_found_memos_should_have_operator
|
197
|
-
|
213
|
+
RecordWithOperator.operator = @user2
|
214
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
198
215
|
note.memos.create!(:body => "memo")
|
199
216
|
assert note.memos.find_all_by_body("memo").all?{|m| m.operator == @user2}
|
200
217
|
end
|
201
218
|
|
202
219
|
def test_found_memo_through_named_scope_should_have_operator
|
203
|
-
|
220
|
+
RecordWithOperator.operator = @user2
|
221
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
204
222
|
note.memos.create!(:body => "memo")
|
205
223
|
assert_equal @user2, note.memos.new_arrivals.first.operator
|
206
224
|
end
|
207
225
|
|
208
226
|
def test_dynamically_found_memo_through_named_scope_should_have_operator
|
209
|
-
|
227
|
+
RecordWithOperator.operator = @user2
|
228
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
210
229
|
note.memos.create!(:body => "memo")
|
211
230
|
assert_equal @user2, note.memos.new_arrivals.find_by_body("memo").operator
|
212
231
|
end
|
213
232
|
|
214
233
|
def test_auto_found_memo_first_should_be_nil_if_note_has_no_memo
|
215
|
-
|
234
|
+
RecordWithOperator.operator = @user2
|
235
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
216
236
|
assert_equal nil, note.memos.first
|
217
237
|
assert_equal nil, note.memos(true).first
|
218
238
|
end
|
219
239
|
|
220
240
|
def test_auto_found_memo_last_should_be_nil_if_note_has_no_memo
|
221
|
-
|
241
|
+
RecordWithOperator.operator = @user2
|
242
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
222
243
|
assert_equal nil, note.memos.last
|
223
244
|
assert_equal nil, note.memos(true).last
|
224
245
|
end
|
225
246
|
|
226
247
|
def test_manualy_found_memo_first_should_be_nil_if_note_has_no_memo
|
227
|
-
|
248
|
+
RecordWithOperator.operator = @user2
|
249
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
228
250
|
assert_equal nil, note.memos.find(:first)
|
229
251
|
end
|
230
252
|
|
231
253
|
def test_manualy_found_memo_last_should_be_nil_if_note_has_no_memo
|
232
|
-
|
254
|
+
RecordWithOperator.operator = @user2
|
255
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
233
256
|
assert_equal nil, note.memos.find(:last)
|
234
257
|
end
|
235
258
|
|
236
259
|
def test_dynamically_found_memos_first_should_be_nil_if_note_has_no_memo
|
237
|
-
|
260
|
+
RecordWithOperator.operator = @user2
|
261
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
238
262
|
assert_equal nil, note.memos.find_all_by_body("memo").first
|
239
263
|
end
|
240
264
|
|
241
265
|
def test_found_memo_through_named_scope_last_should_be_nil_if_note_has_no_memo
|
242
|
-
|
266
|
+
RecordWithOperator.operator = @user2
|
267
|
+
note = NoteWithUser.find(@note_created_by_user1.id)
|
243
268
|
assert_equal nil, note.memos.new_arrivals.last
|
244
269
|
end
|
245
270
|
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
|
+
RecordWithOperator.config[:operator_class_name] = "AdminUser"
|
5
|
+
|
4
6
|
class NoteWithAdminUser < ActiveRecord::Base
|
5
7
|
set_table_name "notes"
|
6
8
|
|
9
|
+
records_with_operator_on :create, :update, :destroy
|
10
|
+
|
7
11
|
def destroy_with_deleted_at
|
8
12
|
NoteWithAdminUser.update_all("deleted_at = '#{Time.now.to_s(:db)}'", "id = #{self.id}")
|
9
13
|
end
|
@@ -23,7 +27,6 @@ end
|
|
23
27
|
|
24
28
|
class RecordWithOperatorUserClassNameTest < ActiveSupport::TestCase
|
25
29
|
def setup
|
26
|
-
RecordWithOperator.config[:user_class_name] = "AdminUser"
|
27
30
|
@user1 = AdminUser.create!(:name => "user1")
|
28
31
|
@user2 = AdminUser.create!(:name => "user2")
|
29
32
|
@note_created_by_user1 = NoteWithAdminUser.create!(:body => "test", :operator => @user1)
|
@@ -43,12 +46,14 @@ class RecordWithOperatorUserClassNameTest < ActiveSupport::TestCase
|
|
43
46
|
end
|
44
47
|
|
45
48
|
def test_note_should_be_found_with_for
|
46
|
-
|
49
|
+
RecordWithOperator.operator = @user2
|
50
|
+
note = NoteWithAdminUser.find(@note_created_by_user1.id)
|
47
51
|
assert_equal(@user2, note.operator)
|
48
52
|
end
|
49
53
|
|
50
54
|
def test_note_should_be_updated_with_updated_by
|
51
|
-
|
55
|
+
RecordWithOperator.operator = @user2
|
56
|
+
note = NoteWithAdminUser.find(@note_created_by_user1.id)
|
52
57
|
note.body = "changed"
|
53
58
|
note.save!
|
54
59
|
assert_equal(@user2.id, note.updated_by)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: record_with_operator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
|
-
- 0
|
8
7
|
- 1
|
9
8
|
- 0
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Yasuko Ohba
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2013-08-28 00:00:00 +09:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -24,14 +24,12 @@ dependencies:
|
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 3
|
30
30
|
segments:
|
31
|
-
- 3
|
32
|
-
- 0
|
33
31
|
- 0
|
34
|
-
version:
|
32
|
+
version: "0"
|
35
33
|
type: :runtime
|
36
34
|
version_requirements: *id001
|
37
35
|
- !ruby/object:Gem::Dependency
|
@@ -99,10 +97,8 @@ files:
|
|
99
97
|
- install.rb
|
100
98
|
- lib/helpers/migration_helper.rb
|
101
99
|
- lib/record_with_operator.rb
|
102
|
-
- lib/record_with_operator/
|
103
|
-
- lib/record_with_operator/
|
104
|
-
- lib/record_with_operator/relation_methods.rb
|
105
|
-
- lib/record_with_operator/utility.rb
|
100
|
+
- lib/record_with_operator/operator.rb
|
101
|
+
- lib/record_with_operator/recorder.rb
|
106
102
|
- lib/record_with_operator/version.rb
|
107
103
|
- lib/tasks/record_with_operator_tasks.rake
|
108
104
|
- record_with_operator.gemspec
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'record_with_operator/utility'
|
2
|
-
|
3
|
-
module RecordWithOperator
|
4
|
-
module Associations
|
5
|
-
module Extension
|
6
|
-
include RecordWithOperator::Utility
|
7
|
-
|
8
|
-
def find(*args)
|
9
|
-
set_operator_to_records(super, @owner.operator)
|
10
|
-
end
|
11
|
-
|
12
|
-
def method_missing(method, *args)
|
13
|
-
set_operator_to_records(super, @owner.operator)
|
14
|
-
end
|
15
|
-
|
16
|
-
protected
|
17
|
-
def construct_scope
|
18
|
-
scoping = super
|
19
|
-
scoping[:find][:for] = @owner.operator
|
20
|
-
scoping
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,146 +0,0 @@
|
|
1
|
-
require 'helpers/migration_helper.rb'
|
2
|
-
|
3
|
-
module RecordWithOperator
|
4
|
-
def self.config
|
5
|
-
@config ||= {:user_class_name => "User", :operator_association_options => {}}
|
6
|
-
@config
|
7
|
-
end
|
8
|
-
|
9
|
-
module Extension
|
10
|
-
extend ActiveSupport::Concern
|
11
|
-
|
12
|
-
included do
|
13
|
-
attr_accessor :operator
|
14
|
-
|
15
|
-
before_create :set_created_by
|
16
|
-
before_save :set_updated_by
|
17
|
-
before_destroy :set_deleted_by
|
18
|
-
|
19
|
-
class << self
|
20
|
-
alias_method_chain :reflections, :operator
|
21
|
-
alias_method_chain :has_many, :operator
|
22
|
-
alias_method_chain :association_accessor_methods, :operator
|
23
|
-
alias_method_chain :association_constructor_method, :operator
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
module ClassMethods
|
28
|
-
def reflections_with_operator
|
29
|
-
create_operator_associations
|
30
|
-
reflections_without_operator
|
31
|
-
end
|
32
|
-
|
33
|
-
def operator_associations_created?
|
34
|
-
@operator_associations_created
|
35
|
-
end
|
36
|
-
|
37
|
-
def create_operator_associations
|
38
|
-
return if operator_associations_created?
|
39
|
-
@operator_associations_created = true
|
40
|
-
|
41
|
-
if self.table_exists?
|
42
|
-
belongs_to :creator, {:foreign_key => "created_by", :class_name => RecordWithOperator.config[:user_class_name]}.merge(RecordWithOperator.config[:operator_association_options]) if column_names.include?('created_by')
|
43
|
-
belongs_to :updater, {:foreign_key => "updated_by", :class_name => RecordWithOperator.config[:user_class_name]}.merge(RecordWithOperator.config[:operator_association_options]) if column_names.include?('updated_by')
|
44
|
-
belongs_to :deleter, {:foreign_key => "deleted_by", :class_name => RecordWithOperator.config[:user_class_name]}.merge(RecordWithOperator.config[:operator_association_options]) if column_names.include?('deleted_by')
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def has_many_with_operator(*args, &extension)
|
49
|
-
options = args.extract_options!
|
50
|
-
# add AssociationWithOprator to :extend
|
51
|
-
if options[:extend]
|
52
|
-
options[:extend] = [options[:extend]] unless options[:extend].kind_of? Array
|
53
|
-
options[:extend] << RecordWithOperator::Associations::Extension
|
54
|
-
else
|
55
|
-
options[:extend] = RecordWithOperator::Associations::Extension
|
56
|
-
end
|
57
|
-
# add :set_operator to :before_add
|
58
|
-
if options[:before_add]
|
59
|
-
options[:before_add] = [options[:before_add]] unless options[:before_add].kind_of? Array
|
60
|
-
options[:before_add] << :set_operator
|
61
|
-
else
|
62
|
-
options[:before_add] = :set_operator
|
63
|
-
end
|
64
|
-
args << options
|
65
|
-
has_many_without_operator(*args, &extension)
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
# define_method association, association= ...
|
70
|
-
def association_accessor_methods_with_operator(reflection, association_proxy_class)
|
71
|
-
association_accessor_methods_without_operator(reflection, association_proxy_class)
|
72
|
-
define_method("#{reflection.name}_with_operator") do |*params|
|
73
|
-
r = send("#{reflection.name}_without_operator", *params)
|
74
|
-
r.operator ||= self.operator if r && r.respond_to?(:operator=)
|
75
|
-
r
|
76
|
-
end
|
77
|
-
alias_method_chain "#{reflection.name}".to_sym, :operator
|
78
|
-
|
79
|
-
define_method("#{reflection.name}_with_operator=") do |new_value|
|
80
|
-
new_value.operator ||= self.operator if new_value.respond_to?(:operator=)
|
81
|
-
send("#{reflection.name}_without_operator=", new_value)
|
82
|
-
end
|
83
|
-
alias_method_chain "#{reflection.name}=".to_sym, :operator
|
84
|
-
end
|
85
|
-
|
86
|
-
# define_method build_association, create_association ...
|
87
|
-
def association_constructor_method_with_operator(constructor, reflection, association_proxy_class)
|
88
|
-
association_constructor_method_without_operator(constructor, reflection, association_proxy_class)
|
89
|
-
define_method("#{constructor}_#{reflection.name}_with_operator") do |*params|
|
90
|
-
options = { :operator => self.operator }
|
91
|
-
params.empty? ? params[0] = options : params.first.merge!(options)
|
92
|
-
self.send("#{constructor}_#{reflection.name}_without_operator", *params)
|
93
|
-
end
|
94
|
-
alias_method_chain "#{constructor}_#{reflection.name}".to_sym, :operator
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
module InstanceMethods
|
99
|
-
def respond_to?(name, priv=false)
|
100
|
-
case name.to_sym
|
101
|
-
when :creator
|
102
|
-
respond_to? :created_by
|
103
|
-
when :updater
|
104
|
-
respond_to? :updated_by
|
105
|
-
when :deleter
|
106
|
-
respond_to? :deleted_by
|
107
|
-
else
|
108
|
-
super
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
def set_operator(child)
|
114
|
-
child.operator ||= self.operator
|
115
|
-
end
|
116
|
-
|
117
|
-
def method_missing(method, *args)
|
118
|
-
return super unless respond_to?(method)
|
119
|
-
case method.to_sym
|
120
|
-
when :creator, :updater, :deleter
|
121
|
-
self.class.create_operator_associations
|
122
|
-
send(method, *args)
|
123
|
-
else
|
124
|
-
super
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def set_created_by
|
129
|
-
return unless respond_to?(:created_by=) && operator
|
130
|
-
self.created_by = operator.id
|
131
|
-
end
|
132
|
-
|
133
|
-
def set_updated_by
|
134
|
-
return unless respond_to?(:updated_by=) && operator && changed? # no use setting updating_by when it's not changed
|
135
|
-
self.updated_by = operator.id
|
136
|
-
end
|
137
|
-
|
138
|
-
def set_deleted_by
|
139
|
-
return unless self.class.column_names.include?("deleted_by") && operator
|
140
|
-
return if frozen?
|
141
|
-
self.class.update_all("deleted_by = #{operator.id}", ["#{self.class.primary_key} = ?", id])
|
142
|
-
self.deleted_by = operator.id
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'record_with_operator/utility'
|
2
|
-
|
3
|
-
module RecordWithOperator
|
4
|
-
module RelationMethods
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
attr_accessor :operator
|
9
|
-
end
|
10
|
-
|
11
|
-
module InstanceMethods
|
12
|
-
include RecordWithOperator::Utility
|
13
|
-
|
14
|
-
def merge(r)
|
15
|
-
merged_relation = super
|
16
|
-
merged_relation.operator ||= r.operator
|
17
|
-
merged_relation
|
18
|
-
end
|
19
|
-
|
20
|
-
def except(*skips)
|
21
|
-
result = super
|
22
|
-
result.operator ||= operator
|
23
|
-
result
|
24
|
-
end
|
25
|
-
|
26
|
-
def only(*onlies)
|
27
|
-
result = super
|
28
|
-
result.operator ||= operator
|
29
|
-
result
|
30
|
-
end
|
31
|
-
|
32
|
-
def for(operator)
|
33
|
-
relation = clone
|
34
|
-
relation.operator ||= operator
|
35
|
-
relation
|
36
|
-
end
|
37
|
-
|
38
|
-
def apply_finder_options(options)
|
39
|
-
finders = options.dup
|
40
|
-
operator = finders.delete(:for)
|
41
|
-
relation = super(finders)
|
42
|
-
relation.for(operator)
|
43
|
-
end
|
44
|
-
|
45
|
-
def find(*args)
|
46
|
-
set_operator_to_records(super, operator)
|
47
|
-
end
|
48
|
-
|
49
|
-
def first(*args)
|
50
|
-
set_operator_to_records(super, operator)
|
51
|
-
end
|
52
|
-
|
53
|
-
def last(*args)
|
54
|
-
set_operator_to_records(super, operator)
|
55
|
-
end
|
56
|
-
|
57
|
-
def all(*args)
|
58
|
-
set_operator_to_records(super, operator)
|
59
|
-
end
|
60
|
-
|
61
|
-
def to_a
|
62
|
-
set_operator_to_records(super, operator)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module RecordWithOperator
|
2
|
-
module Utility
|
3
|
-
private
|
4
|
-
def set_operator_to_records(records, operator)
|
5
|
-
return records unless operator
|
6
|
-
|
7
|
-
unless ActiveRecord::Relation === records
|
8
|
-
if records.respond_to?(:operator=)
|
9
|
-
records.operator = operator
|
10
|
-
elsif Array === records
|
11
|
-
records.each do |record|
|
12
|
-
record.operator = operator if record.respond_to?(:operator=)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
records
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|