has_moderated 1.0.rc6 → 1.0.rc7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +33 -2
- data/lib/has_moderated/moderation_model.rb +9 -3
- data/lib/has_moderated/moderation_preview.rb +38 -6
- data/lib/has_moderated/version.rb +1 -1
- data/test/dummy/log/test.log +19110 -0
- data/test/dummy/spec/models/task_spec.rb +36 -0
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Add it to your project's Gemfile
|
7
7
|
|
8
|
-
gem "has_moderated", ">=1.0.
|
8
|
+
gem "has_moderated", ">=1.0.rc7"
|
9
9
|
|
10
10
|
and run
|
11
11
|
|
@@ -125,7 +125,19 @@ It also supports dirty tracking through ActiveModel, so you can use all its func
|
|
125
125
|
preview.some_attr_change # => ["old value", "new value"]
|
126
126
|
preview.some_association.first # => #<HasModerated::FakeTask @fake_of_model=Task, @attributes={"id"=>1, "title"=>"Task 1", "desc"=>nil, "created_at"=>"2012-06-08 15:49:56.726646", "updated_at"=>"2012-06-08 15:49:56.726646"}, @changed_attributes={}, reflections.keys => [:assoc1, :assoc2]>
|
127
127
|
|
128
|
-
This preview is cached from applying the moderation in a transaction and then rolling it back (so it does not
|
128
|
+
This preview is cached from applying the moderation in a transaction and then rolling it back (so it does not affect the database).
|
129
|
+
|
130
|
+
=== Using the fake object to modify the moderation
|
131
|
+
|
132
|
+
The fake object described above has a nifty feature (1.0.rc7+) that allows you to update attributes in the moderation by manipulating the fake object. Right now it can only handle attributes and not associations, but that might change in the future. See example below on how to use this feature.
|
133
|
+
|
134
|
+
moderation.parsed_data # => {:attributes=>{"title"=>"Task 1"}}
|
135
|
+
preview = moderation.preview(:saveable => true)
|
136
|
+
preview.title = "Task 2"
|
137
|
+
preview.update_moderation
|
138
|
+
moderation.parsed_data # => {:attributes=>{"title"=>"Task 2"}}
|
139
|
+
moderation.apply
|
140
|
+
Task.first.title # => "Task 2"
|
129
141
|
|
130
142
|
=== Get a real ActiveRecord preview
|
131
143
|
|
@@ -139,6 +151,25 @@ This way, you will get a real ActiveRecord object that is really in the database
|
|
139
151
|
preview.some_association.first # => ActiveRecord object
|
140
152
|
end
|
141
153
|
|
154
|
+
Note that since a transaction is used in both cases, all the changes made to the database to produce the preview are only in effect inside the transaction, so the changes are only visible inside the transaction. For example, if a second database query comes from another Rails instance, it will not see the changes that are in effect in the transaction, even if the transaction is still in process.
|
155
|
+
|
156
|
+
=== Example of using preview in your show action
|
157
|
+
|
158
|
+
In this example I allow admin users to add a preview parameter to the URL to see the preview of how the record will look after applying a moderation, without having to change code in the views.
|
159
|
+
|
160
|
+
def show
|
161
|
+
@doctor = Doctor.find_by_slug(params[:id])
|
162
|
+
|
163
|
+
if current_admin_user && params[:preview]
|
164
|
+
@doctor.moderations.find_by_id(params[:preview]).live_preview do |preview|
|
165
|
+
@doctor = preview
|
166
|
+
render :action => "show"
|
167
|
+
end
|
168
|
+
else
|
169
|
+
render :action => "show"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
142
173
|
== Which kind of moderation is it?
|
143
174
|
|
144
175
|
You can call the following convenience methods to determine the type of moderation
|
@@ -44,18 +44,24 @@ module HasModerated
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def live_preview
|
47
|
-
|
47
|
+
self.transaction do
|
48
48
|
record = accept
|
49
49
|
yield(record)
|
50
50
|
raise ActiveRecord::Rollback
|
51
51
|
end
|
52
|
+
# self.frozen? now became true
|
53
|
+
# since we don't actually commit to database, we don't need the freeze
|
54
|
+
# only way I found to unfreeze is to dup attributes
|
55
|
+
@attributes = @attributes.dup
|
56
|
+
|
52
57
|
nil
|
53
58
|
end
|
54
59
|
|
55
|
-
def preview
|
60
|
+
def preview(options = {})
|
61
|
+
options[:saveable] ||= false
|
56
62
|
fake_record = nil
|
57
63
|
live_preview do |record|
|
58
|
-
fake_record = HasModerated::Preview::from_live(record)
|
64
|
+
fake_record = HasModerated::Preview::from_live(record, self, options[:saveable])
|
59
65
|
end
|
60
66
|
fake_record
|
61
67
|
end
|
@@ -1,6 +1,25 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
module HasModerated
|
3
3
|
module Preview
|
4
|
+
module Saveable
|
5
|
+
def update_moderation
|
6
|
+
if @based_on_moderation.present?
|
7
|
+
data = @based_on_moderation.parsed_data
|
8
|
+
|
9
|
+
# attributes
|
10
|
+
data[:attributes] ||= Hash.new
|
11
|
+
@attributes.each_pair do |key, value|
|
12
|
+
if value != @attributes_initial[key]
|
13
|
+
data[:attributes][key.to_s] = value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
@based_on_moderation.data = data
|
18
|
+
@based_on_moderation.save
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
4
23
|
class FakeRecord
|
5
24
|
extend ActiveModel::Naming
|
6
25
|
include ActiveModel::Conversion
|
@@ -8,8 +27,9 @@ module HasModerated
|
|
8
27
|
|
9
28
|
attr_accessor :attributes
|
10
29
|
|
11
|
-
def initialize(
|
12
|
-
@
|
30
|
+
def initialize(based_on_model, based_on_moderation)
|
31
|
+
@based_on_model = based_on_model
|
32
|
+
@based_on_moderation = based_on_moderation
|
13
33
|
end
|
14
34
|
|
15
35
|
def persisted?
|
@@ -25,7 +45,7 @@ module HasModerated
|
|
25
45
|
end
|
26
46
|
|
27
47
|
def to_s
|
28
|
-
"#<HasModerated::Fake#{@
|
48
|
+
"#<HasModerated::Fake#{@based_on_model.to_s}>"
|
29
49
|
end
|
30
50
|
|
31
51
|
def inspect
|
@@ -47,15 +67,16 @@ module HasModerated
|
|
47
67
|
if cache[record.class][record.id].present?
|
48
68
|
cache[record.class][record.id]
|
49
69
|
else
|
50
|
-
cache[record.class][record.id] = from_live(record, cache)
|
70
|
+
cache[record.class][record.id] = from_live(record, nil, false, cache)
|
51
71
|
end
|
52
72
|
end
|
53
73
|
|
54
|
-
def self.from_live(record, object_cache = nil)
|
74
|
+
def self.from_live(record, moderation = nil, saveable = false, object_cache = nil)
|
55
75
|
return nil if record.blank?
|
56
|
-
obj = FakeRecord.new(record.class)
|
76
|
+
obj = FakeRecord.new(record.class, moderation)
|
57
77
|
eigenclass = (class << obj ; self ; end)
|
58
78
|
|
79
|
+
# attributes
|
59
80
|
obj.instance_variable_set(:@attributes, record.instance_variable_get(:@attributes))
|
60
81
|
changed_attributes = Hash.new
|
61
82
|
record.previous_changes.each_pair do |attr_name, values|
|
@@ -63,6 +84,17 @@ module HasModerated
|
|
63
84
|
end
|
64
85
|
obj.instance_variable_set(:@changed_attributes, changed_attributes)
|
65
86
|
|
87
|
+
# saveable
|
88
|
+
if saveable
|
89
|
+
obj.instance_variable_set(:@attributes_initial, record.instance_variable_get(:@attributes).dup)
|
90
|
+
eigenclass.send(:include, Saveable)
|
91
|
+
obj.attributes.keys.each do |attr_name|
|
92
|
+
eigenclass.send(:define_method, "#{attr_name}=") do |value|
|
93
|
+
self.attributes[attr_name.to_s] = value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
66
98
|
# associations
|
67
99
|
object_cache ||= Hash.new
|
68
100
|
object_cache[record.class] ||= Hash.new
|