immortal 0.1.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,28 +1,32 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- immortal (0.1.7)
5
- activerecord (~> 3.0.5)
4
+ immortal (0.1.6)
5
+ activerecord (= 3.1.0)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- activemodel (3.0.9)
11
- activesupport (= 3.0.9)
12
- builder (~> 2.1.2)
13
- i18n (~> 0.5.0)
14
- activerecord (3.0.9)
15
- activemodel (= 3.0.9)
16
- activesupport (= 3.0.9)
17
- arel (~> 2.0.10)
18
- tzinfo (~> 0.3.23)
19
- activesupport (3.0.9)
20
- arel (2.0.10)
21
- builder (2.1.2)
10
+ activemodel (3.1.0)
11
+ activesupport (= 3.1.0)
12
+ bcrypt-ruby (~> 3.0.0)
13
+ builder (~> 3.0.0)
14
+ i18n (~> 0.6)
15
+ activerecord (3.1.0)
16
+ activemodel (= 3.1.0)
17
+ activesupport (= 3.1.0)
18
+ arel (~> 2.2.1)
19
+ tzinfo (~> 0.3.29)
20
+ activesupport (3.1.0)
21
+ multi_json (~> 1.0)
22
+ arel (2.2.1)
23
+ bcrypt-ruby (3.0.1)
24
+ builder (3.0.0)
22
25
  columnize (0.3.2)
23
26
  diff-lcs (1.1.2)
24
- i18n (0.5.0)
27
+ i18n (0.6.0)
25
28
  linecache (0.43)
29
+ multi_json (1.0.3)
26
30
  rspec (2.3.0)
27
31
  rspec-core (~> 2.3.0)
28
32
  rspec-expectations (~> 2.3.0)
@@ -36,7 +40,7 @@ GEM
36
40
  ruby-debug-base (~> 0.10.4.0)
37
41
  ruby-debug-base (0.10.4)
38
42
  linecache (>= 0.3)
39
- sqlite3-ruby (1.3.2)
43
+ sqlite3 (1.3.4)
40
44
  tzinfo (0.3.29)
41
45
 
42
46
  PLATFORMS
@@ -46,4 +50,4 @@ DEPENDENCIES
46
50
  immortal!
47
51
  rspec (~> 2.3.0)
48
52
  ruby-debug (~> 0.10.4)
49
- sqlite3-ruby (~> 1.3.2)
53
+ sqlite3
data/README.md CHANGED
@@ -44,6 +44,8 @@ If you want to improve immortal
44
44
 
45
45
  ## CHANGELOG
46
46
 
47
+ - 1.0.0 Changed the API, made it compatible with Rails 3.1, removed
48
+ functionality
47
49
  - 0.1.6 Fixing immortal issue 2: with_deleted breaks associations
48
50
  - 0.1.5 Add "without deleted" scope to join model by overriding HasManyThroughAssociation#construct_conditions
49
51
  rather than simply adding to has_many conditions.
data/immortal.gemspec CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "immortal"
6
- s.version = '0.1.7'
6
+ s.version = '1.0.0'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Jordi Romero", "Saimon Moore"]
9
9
  s.email = ["jordi@jrom.net", "saimon@saimonmoore.net"]
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
16
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
17
  s.require_paths = ["lib"]
18
18
 
19
- s.add_dependency 'activerecord', '~> 3.0.5'
19
+ s.add_dependency 'activerecord', '3.1.0'
20
20
  s.add_development_dependency 'rspec', '~> 2.3.0'
21
- s.add_development_dependency 'sqlite3-ruby', '~> 1.3.2'
21
+ s.add_development_dependency 'sqlite3'
22
22
  s.add_development_dependency 'ruby-debug', '~> 0.10.4'
23
23
  end
data/lib/immortal.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'immortal/has_many_through_mortal_association'
2
-
3
1
  module Immortal
4
2
 
5
3
  def self.included(base)
@@ -12,11 +10,7 @@ module Immortal
12
10
  # from the join model
13
11
  def has_many_mortal(association_id, options = {}, &extension)
14
12
  has_many_immortal(association_id, options, &extension).tap do
15
- if options[:through] and reflections[options[:through]] and reflections[options[:through]].class_name.classify.constantize.arel_table[:deleted]
16
- reflection = reflect_on_association(association_id)
17
- collection_reader_method(reflection, Immortal::HasManyThroughMortalAssociation)
18
- collection_accessor_methods(reflection, Immortal::HasManyThroughMortalAssociation, false)
19
- end
13
+ # FIXME This must be re-implemented after the ActiveRecord internals refactor in 3.1
20
14
  end
21
15
  end
22
16
 
@@ -35,32 +29,38 @@ module Immortal
35
29
  self.included_modules.include?(::Immortal::InstanceMethods)
36
30
  end
37
31
 
38
- def with_deleted
39
- except(:where).where(filter_undeleted_where_clauses.join(' AND '))
32
+ def without_default_scope
33
+ with_exclusive_scope do
34
+ yield
35
+ end
40
36
  end
41
37
 
42
- def only_deleted
43
- deleted_clause = arel_table[:deleted].eq(true)
44
- where_sql_clauses = filter_undeleted_where_clauses
45
- where_sql_clauses.concat unscoped.where(deleted_clause).where_clauses
46
-
47
- except(:where).where(where_sql_clauses.join(" AND "))
38
+ def exists?(id = false)
39
+ where(:deleted => false).exists?(id)
48
40
  end
49
41
 
50
42
  def count_with_deleted(*args)
51
- with_deleted.count(*args)
43
+ without_default_scope do
44
+ count(*args)
45
+ end
52
46
  end
53
47
 
54
48
  def count_only_deleted(*args)
55
- only_deleted.count(*args)
49
+ without_default_scope do
50
+ where(:deleted => true).count(*args)
51
+ end
56
52
  end
57
53
 
58
54
  def find_with_deleted(*args)
59
- with_deleted.find(*args)
55
+ without_default_scope do
56
+ find(*args)
57
+ end
60
58
  end
61
59
 
62
60
  def find_only_deleted(*args)
63
- only_deleted.find(*args)
61
+ without_default_scope do
62
+ where(:deleted => true).find(*args)
63
+ end
64
64
  end
65
65
 
66
66
  def immortal_delete_all(conditions = nil)
@@ -72,24 +72,11 @@ module Immortal
72
72
  end
73
73
 
74
74
  def undeleted_clause_sql
75
- unscoped.where(arel_table[:deleted].eq(nil).or(arel_table[:deleted].eq(false))).where_clauses.first
75
+ unscoped.where(arel_table[:deleted].eq(nil).or(arel_table[:deleted].eq(false))).constraints.first.to_sql
76
76
  end
77
77
 
78
78
  def deleted_clause_sql
79
- unscoped.where(arel_table[:deleted].eq(true)).where_clauses.first
80
- end
81
-
82
- private
83
-
84
- def filter_undeleted_where_clauses
85
- where_clauses = scoped.arel.send(:where_clauses)
86
-
87
- #Yes it's an ugly hack but I couldn't find a cleaner way of doing this
88
- filtered_clauses = where_clauses.dup.map do |clause|
89
- clause.gsub(/(\s+AND\s+)?\("?`?(\w+)`?"?."?`?deleted`?"?\sIS\sNULL[^\)]+\)/, '')
90
- end.map {|cl| cl.gsub("()", '')}.select {|cl| !cl.empty?}
91
-
92
- filtered_clauses
79
+ unscoped.where(arel_table[:deleted].eq(true)).constraints.first.to_sql
93
80
  end
94
81
 
95
82
  end
@@ -38,12 +38,6 @@ describe Immortal do
38
38
  ImmortalModel.all.should be_empty
39
39
  end
40
40
 
41
- it "should find deleted records using scope" do
42
- @m.destroy
43
- ImmortalModel.with_deleted.first.should == @m
44
- ImmortalModel.with_deleted.all.should include(@m)
45
- end
46
-
47
41
  it "should find deleted records using the old method" do
48
42
  ImmortalModel.find_with_deleted(@m.id).should == @m
49
43
  @m.destroy
@@ -53,12 +47,10 @@ describe Immortal do
53
47
  it "should count undeleted records by default" do
54
48
  @m2 = ImmortalModel.create! :title => 'testing immortal again'
55
49
  ImmortalModel.count_only_deleted.should == 0
56
- ImmortalModel.only_deleted.count.should == 0
57
50
 
58
51
  @m.destroy
59
52
 
60
53
  ImmortalModel.count_only_deleted.should == 1
61
- ImmortalModel.only_deleted.count.should == 1
62
54
  end
63
55
 
64
56
  it "should find only deleted records" do
@@ -67,19 +59,12 @@ describe Immortal do
67
59
  ImmortalModel.find_only_deleted(@m.id)
68
60
  }.to raise_error(ActiveRecord::RecordNotFound)
69
61
 
70
- expect {
71
- ImmortalModel.only_deleted.find(@m.id)
72
- }.to raise_error(ActiveRecord::RecordNotFound)
73
-
74
62
  @m.destroy
75
63
 
76
64
  ImmortalModel.find_only_deleted(@m.id).should == @m
77
65
  expect {
78
66
  ImmortalModel.find_only_deleted(@m2.id)
79
67
  }.to raise_error(ActiveRecord::RecordNotFound)
80
-
81
- ImmortalModel.only_deleted.should include(@m)
82
- ImmortalModel.only_deleted.should_not include(@m2)
83
68
  end
84
69
 
85
70
  it "should be able to count undeleted records" do
@@ -95,7 +80,6 @@ describe Immortal do
95
80
  @m2 = ImmortalModel.create! :title => 'testing immortal again'
96
81
  @m.destroy
97
82
  ImmortalModel.count_with_deleted.should == 2
98
- ImmortalModel.with_deleted.count.should == 2
99
83
  end
100
84
 
101
85
  it "should not exist if deleted" do
@@ -152,7 +136,7 @@ describe Immortal do
152
136
  it "should immortally delete all records with delete_all!" do
153
137
  expect {
154
138
  ImmortalModel.delete_all!
155
- }.to change(ImmortalModel.with_deleted, :count).by(-1)
139
+ }.to change(ImmortalModel, :count_with_deleted).by(-1)
156
140
  end
157
141
 
158
142
  it "should know if it's deleted" do
@@ -163,7 +147,7 @@ describe Immortal do
163
147
 
164
148
  it "should be recoverable" do
165
149
  @m.destroy
166
- @m = ImmortalModel.with_deleted.find(@m.id)
150
+ @m = ImmortalModel.find_with_deleted(@m.id)
167
151
  @m.recover!
168
152
  @m.should_not be_frozen
169
153
  @m.should_not be_changed
@@ -207,41 +191,11 @@ describe Immortal do
207
191
  end
208
192
 
209
193
  it "should properly generate joins" do
210
- join_sql = 'INNER JOIN "immortal_joins" ON "immortal_nodes"."id" = "immortal_joins"."immortal_node_id" INNER JOIN "immortal_models" ON "immortal_models"."id" = "immortal_joins"."immortal_model_id"'
211
- ImmortalNode.joins(:immortal_models).to_sql.should include(join_sql)
212
- end
213
-
214
- it "should not unscope associations when using with_deleted scope" do
215
- m1 = ImmortalModel.create! :title => 'previously created model'
216
- n1 = ImmortalNode.create! :title => 'previously created association'
217
- j1 = ImmortalJoin.create! :immortal_model => m1, :immortal_node => n1
218
-
219
- @n = ImmortalNode.create! :title => 'testing association'
220
- @join = ImmortalJoin.create! :immortal_model => @m, :immortal_node => @n
221
-
222
- @join.destroy
223
-
224
- @m.nodes.count.should == 0
225
- @n.joins.count.should == 0
226
-
227
- @m.nodes.with_deleted.count.should == 1
228
- @n.joins.with_deleted.count.should == 1
194
+ join_sql1 = 'INNER JOIN "immortal_joins" ON "immortal_joins"."immortal_node_id" = "immortal_nodes"."id"'
195
+ join_sql2 = 'INNER JOIN "immortal_models" ON "immortal_models"."id" = "immortal_joins"."immortal_model_id"'
196
+ generated_sql = ImmortalNode.joins(:immortal_models).to_sql
197
+ generated_sql.should include(join_sql1)
198
+ generated_sql.should include(join_sql2)
229
199
  end
230
200
 
231
- it "should not unscope associations when using only_deleted scope" do
232
- m1 = ImmortalModel.create! :title => 'previously created model'
233
- n1 = ImmortalNode.create! :title => 'previously created association'
234
- j1 = ImmortalJoin.create! :immortal_model => m1, :immortal_node => n1
235
-
236
- @n = ImmortalNode.create! :title => 'testing association'
237
- @join = ImmortalJoin.create! :immortal_model => @m, :immortal_node => @n
238
-
239
- @join.destroy
240
-
241
- @m.nodes.count.should == 0
242
- @n.joins.count.should == 0
243
-
244
- @m.nodes.only_deleted.count.should == 1
245
- @n.joins.only_deleted.count.should == 1
246
- end
247
201
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: immortal
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
- - 0
8
7
  - 1
9
- - 7
10
- version: 0.1.7
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jordi Romero
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-08-30 00:00:00 +02:00
19
+ date: 2011-09-28 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -25,14 +25,14 @@ dependencies:
25
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
26
  none: false
27
27
  requirements:
28
- - - ~>
28
+ - - "="
29
29
  - !ruby/object:Gem::Version
30
- hash: 13
30
+ hash: 3
31
31
  segments:
32
32
  - 3
33
+ - 1
33
34
  - 0
34
- - 5
35
- version: 3.0.5
35
+ version: 3.1.0
36
36
  type: :runtime
37
37
  version_requirements: *id001
38
38
  - !ruby/object:Gem::Dependency
@@ -52,19 +52,17 @@ dependencies:
52
52
  type: :development
53
53
  version_requirements: *id002
54
54
  - !ruby/object:Gem::Dependency
55
- name: sqlite3-ruby
55
+ name: sqlite3
56
56
  prerelease: false
57
57
  requirement: &id003 !ruby/object:Gem::Requirement
58
58
  none: false
59
59
  requirements:
60
- - - ~>
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
- hash: 31
62
+ hash: 3
63
63
  segments:
64
- - 1
65
- - 3
66
- - 2
67
- version: 1.3.2
64
+ - 0
65
+ version: "0"
68
66
  type: :development
69
67
  version_requirements: *id003
70
68
  - !ruby/object:Gem::Dependency
@@ -101,7 +99,6 @@ files:
101
99
  - Rakefile
102
100
  - immortal.gemspec
103
101
  - lib/immortal.rb
104
- - lib/immortal/has_many_through_mortal_association.rb
105
102
  - spec/immortal_spec.rb
106
103
  - spec/spec_helper.rb
107
104
  has_rdoc: true
@@ -1,23 +0,0 @@
1
- require 'active_record'
2
-
3
- module Immortal
4
-
5
- class HasManyThroughMortalAssociation < ActiveRecord::Associations::HasManyThroughAssociation
6
- protected
7
-
8
- def construct_conditions
9
- klass = @reflection.through_reflection.klass
10
- return super unless klass.respond_to?(:immortal?) && klass.immortal?
11
- table_name = @reflection.through_reflection.quoted_table_name
12
- conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value|
13
- "#{table_name}.#{attr} = #{value}"
14
- end
15
-
16
- deleted_conditions = ["#{table_name}.deleted IS NULL OR #{table_name}.deleted = ?", false]
17
- conditions << klass.send(:sanitize_sql, deleted_conditions)
18
- conditions << sql_conditions if sql_conditions
19
- "(" + conditions.join(') AND (') + ")"
20
- end
21
- end
22
-
23
- end