has_moderated 1.0.alpha → 1.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -25,7 +25,7 @@ When upgrading, rerun the generator
25
25
 
26
26
  rails generate has_moderated:install
27
27
 
28
- If there is a new migration file and you have filename conflicts, remove the old one and apply the new one, in case the schema changed.
28
+ If there is a new migration file and you have filename conflicts, remove the old one and apply the new one, in case the schema changed. This is especially important if you are upgrading from a previous version to v1.x.
29
29
 
30
30
  == Why use this instead of something like Papertrail?
31
31
 
@@ -65,20 +65,18 @@ To moderate destruction of records, use
65
65
 
66
66
  Warning! Always put has_many etc. BEFORE has_moderated calls in your model!
67
67
 
68
- == Moderating associations on existing records
69
- There is an automatic way to moderate associations on already-created records. Use:
68
+ == Moderating associations
69
+ To moderate associations use:
70
70
 
71
71
  has_moderated_association :links, :comments
72
72
 
73
73
  to moderate the links and comments associations. You can use :all to moderate all associations, but I recommend you explicitly specify them.
74
74
 
75
- You can also manually add associations to moderation like so
75
+ Be especially careful if you are moderating a has_many :through association. In this case, you must moderate both associations. For example:
76
76
 
77
- post.add_associations_moderated(:comments => [new_comment], :scores => [new_score])
78
-
79
- The values can be either new records (not in the database), existing records, or Fixnum (numerical) IDs. Please note in this case you should not use .build to create new records, because if you call save on the parent model it will automatically create the record (this only applies if you use the manual way).
80
-
81
- Moderation for removing associated records from existing records was added in version 0.0.32 (automatic).
77
+ has_many :bookshelves
78
+ has_many :books, :through => :bookshelves
79
+ has_moderated_association :bookshelves, :books
82
80
 
83
81
  == Manage moderations
84
82
  To see pending moderations, simply call
@@ -90,9 +88,9 @@ You can also see moderations for a specific record. For example, if you have Pos
90
88
  post = Post.first
91
89
  post.moderations
92
90
 
93
- Moderation is a normal ActiveRecord model, you can inspect it in rails console to see what it holds. Data (attr_value) is serialized in YAML format and can be deserialized by calling
91
+ Moderation is a normal ActiveRecord model, you can inspect it in rails console to see what it holds. Data is serialized in YAML format and can be deserialized by calling
94
92
 
95
- YAML::load(moderation.attr_value)
93
+ YAML::load(moderation.data)
96
94
 
97
95
  To accept a moderation, call
98
96
 
@@ -101,11 +99,13 @@ To accept a moderation, call
101
99
  to discard (destroy) it, call
102
100
 
103
101
  moderation.discard
102
+
103
+ Do not use moderation.destroy, because discard triggers certain callbacks which may be necessary.
104
104
 
105
105
  == Bypassing moderation
106
- To bypass moderation (e.g. for admin users), wrap your code into moderatable_updating like so:
106
+ To bypass moderation (e.g. for admin users), wrap your code into without_moderation like so:
107
107
 
108
- record.moderatable_updating(current_user.is_admin?)
108
+ record.without_moderation(current_user.is_admin?) do
109
109
  record.update_attributes(...)
110
110
  end
111
111
 
@@ -131,7 +131,7 @@ For example you have a Comment model, and it is moderated. But your visitors are
131
131
  m.user_id = self.moderation_user_id
132
132
  end
133
133
 
134
- This is just one example on how to do it. You need the attr_accessor here because we are going to pass the user ID from the controller. In the hook you have access to the Moderation model just before it is saved, so you can modify it like any other model. Now just set moderation_user_id on the model before you save it:
134
+ This is just one example how you can do it. You need the attr_accessor here because we are going to pass the user ID from the controller. In the hook you have access to the Moderation model just before it is saved, so you can modify it like any other model. Now just set moderation_user_id on the model before you save it:
135
135
 
136
136
  c = Comment.new
137
137
  c.moderation_user_id = current_user.id
@@ -164,9 +164,16 @@ You can run the tests by running
164
164
 
165
165
  in the root directory of this gem (so you have to clone it first).
166
166
 
167
- == NOTES
168
- - to moderate has_many :through assoc, must add both associations to moderation
169
- == TODO
167
+ == Problems
168
+
169
+ If you have problems open an issue here on Github.
170
+
171
+ You may encounter problems with models that have some sort of non-serializable attributes. This might be something like file attachments, you'll have to try it to see.
172
+ If you have a problem like that you can extract the problematic attributes into a seperate has_one association. If you moderate create, save that model without the foreign key first, and then use has_moderated_create :with_associations => [:association_name] and add the association (to the existing associated model) before saving the moderated model. If you have questions about this or don't understand what I mean, open an issue here at GitHub and I will explain it further.
173
+
174
+ It is also possible you will encounter problems with some heavily customized associations, or with has_many :through associations (although I have tested this for a simple, ordinary case and it works). If that happens open an issue here on Github.
175
+
176
+ == My personal TODO (ignore this)
170
177
 
171
178
  This is just for my personal todo list...
172
179
 
@@ -187,15 +194,6 @@ make hasone, hasmany etc. each a separate "extension" (like carrierwave). for te
187
194
  Amend moderations... Eg if you create a new record and save it, then change something additionally and save again.
188
195
  Preview method which gives changed object but doesnt save it.
189
196
 
190
- == Problems
191
-
192
- If you have problems open an issue here on Github.
193
-
194
- You may encounter problems with models that have some sort of non-serializable attributes. This might be something like file attachments, you'll have to try it to see.
195
- If you have a problem like that you can extract the problematic attributes into a seperate has_one association. If you moderate create, save that model without the foreign key first, and then use has_moderated_create :with_associations => [:association_name] and add the association (to the existing associated model) before saving the moderated model. If you have questions about this or don't understand what I mean, open an issue here at GitHub and I will explain it further.
196
-
197
- It is also possible you will encounter problems with some heavily customized associations, or with has_many :through associations (although I have tested this for a simple, ordinary case and it works). If that happens open an issue here on Github.
198
-
199
197
  == License
200
198
 
201
199
  This project rocks and uses MIT-LICENSE.
@@ -2,8 +2,8 @@ module HasModerated
2
2
  module Associations
3
3
  module Base
4
4
 
5
- # Class methods included into ActiveRecord::Base so that you can call them in
6
- # your ActiveRecord models.
5
+ # Class methods included into ActiveRecord::Base so that they can be called in
6
+ # ActiveRecord models.
7
7
  module ClassMethods
8
8
 
9
9
  # Will moderate the passed in associations if they are supported.
@@ -35,6 +35,9 @@ module HasModerated
35
35
  when :has_one then
36
36
  self.send :extend, HasModerated::Associations::HasOne::ClassMethods
37
37
  has_moderated_has_one_association(assoc)
38
+ when :has_and_belongs_to_many then
39
+ self.send :extend, HasModerated::Associations::HasMany::ClassMethods
40
+ has_moderated_has_many_association(assoc)
38
41
  else raise "don't know how to moderate association macro #{assoc.macro}"
39
42
  end
40
43
  end
@@ -50,8 +53,8 @@ module HasModerated
50
53
  def self.add_assoc_to_record(to, assoc_id, reflection)
51
54
  return unless to && assoc_id
52
55
 
53
- # TODO has_one weirness?
54
- if reflection.macro == :has_many
56
+ # TODO has_one weirdness?
57
+ if reflection.macro == :has_many || reflection.macro == :has_and_belongs_to_many
55
58
  HasModerated::Associations::Collection::AssociationHelpers::add_assoc_to_record(to, assoc_id, reflection)
56
59
  end
57
60
  end
@@ -58,7 +58,7 @@ module HasModerated
58
58
  !(assoc.options[:join_table] && assoc.options[:join_table].to_s == join_table)
59
59
  end
60
60
  if results.count != 1
61
- raise "has_moderated: Cannot determine join table for a Habtm association!"
61
+ raise "has_moderated: Cannot determine join table for a Habtm association! Are you missing has_and_belongs_to_many in one of your models?"
62
62
  end
63
63
  results.first[1].name.to_s
64
64
  elsif reflection.options[:through].present?
@@ -25,7 +25,6 @@ module HasModerated
25
25
 
26
26
  # calls user hooks for creation of a new moderation
27
27
  def self.call_creating_hook model, moderation
28
- #todo use model.class.moderation_hooks[:creating_moderation]
29
28
  if model.class.respond_to?(:moderation_hooks)
30
29
  model.class.moderation_hooks[:creating] ||= []
31
30
  model.class.moderation_hooks[:creating].each do |hook|
@@ -1,3 +1,3 @@
1
1
  module HasModerated
2
- VERSION = "1.0.alpha"
2
+ VERSION = "1.0.alpha2"
3
3
  end
@@ -0,0 +1,30 @@
1
+ guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
2
+ watch('config/application.rb')
3
+ watch('config/environment.rb')
4
+ watch(%r{^config/environments/.+\.rb$})
5
+ watch(%r{^config/initializers/.+\.rb$})
6
+ watch('Gemfile')
7
+ watch('Gemfile.lock')
8
+ watch('../../lib/has_moderated/associations/base.rb')
9
+ watch('spec/spec_helper.rb') { :rspec }
10
+ watch('test/test_helper.rb') { :test_unit }
11
+ watch(%r{features/support/}) { :cucumber }
12
+ watch(%r{^spec/support/.+\.rb$}) { :rspec }
13
+ end
14
+
15
+ guard 'rspec', :version => 2, :cli => '--drb', :all_after_pass => false do
16
+ watch(%r{^spec/.+_spec\.rb$})
17
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
18
+ watch('spec/spec_helper.rb') { "spec" }
19
+
20
+ # Rails example
21
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
22
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
23
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
24
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
25
+ watch('config/routes.rb') { "spec/routing" }
26
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
27
+ # Capybara request specs
28
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
29
+ end
30
+