scoped_associations 0.0.6 → 0.1.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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +0 -7
- data/Appraisals +0 -5
- data/Gemfile +0 -1
- data/README.md +6 -0
- data/lib/scoped_associations/activerecord4/has_many.rb +23 -9
- data/lib/scoped_associations/activerecord4/has_one.rb +23 -9
- data/lib/scoped_associations/version.rb +1 -2
- data/scoped_associations.gemspec +4 -4
- data/spec/has_many_polymorphic_spec.rb +74 -0
- data/spec/has_many_spec.rb +74 -0
- data/spec/has_one_polymorphic_spec.rb +63 -0
- data/spec/has_one_spec.rb +61 -0
- data/spec/integration_spec.rb +0 -1
- data/spec/spec_helper.rb +65 -20
- metadata +29 -7
- data/gemfiles/activerecord30.gemfile +0 -8
- data/lib/scoped_associations/activerecord3/has_many.rb +0 -63
- data/lib/scoped_associations/activerecord3/has_one.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e04ccbeb140afbf311d49706224e27f270945e24
|
4
|
+
data.tar.gz: 357ec935059c9e0657f1eba5b22e35ddce8b31cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 665ce8e29af580228fa003f7f9348a14ffedab668cef5ebff06b6eaabb41ea54b7b799060cd4948f9eded1afef0aa3ecaeda612516333b2e21f060aa9512d027
|
7
|
+
data.tar.gz: bcb5ac38011ce283316dec718b0a1711cf88748413b9b93b41fc353a34eb2d70c98a8ac59cfd43260410e7991270e5aeb1e45ce7c88ae3e6aca560bfb638e8e2
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
CHANGED
@@ -6,15 +6,8 @@ rvm:
|
|
6
6
|
- "2.2.2"
|
7
7
|
|
8
8
|
gemfile:
|
9
|
-
- "gemfiles/activerecord30.gemfile"
|
10
9
|
- "gemfiles/activerecord40.gemfile"
|
11
10
|
- "gemfiles/activerecord41.gemfile"
|
12
11
|
- "gemfiles/activerecord42.gemfile"
|
13
12
|
|
14
|
-
matrix:
|
15
|
-
exclude:
|
16
|
-
- rvm: "2.2.2"
|
17
|
-
gemfile: "gemfiles/activerecord30.gemfile"
|
18
|
-
|
19
13
|
script: "bundle exec rake spec"
|
20
|
-
|
data/Appraisals
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,10 +7,15 @@ ScopedAssociations is able to create multiple `has_to` and `has_many`
|
|
7
7
|
associations between two ActiveRecord models.
|
8
8
|
|
9
9
|
## Installation
|
10
|
+
Scoped Association works on Rails4+
|
10
11
|
|
11
12
|
Add this line to your application's Gemfile:
|
12
13
|
|
13
14
|
gem 'scoped_associations'
|
15
|
+
|
16
|
+
If you need it on a Rails3.2 project (without .joins support), add this one:
|
17
|
+
|
18
|
+
gem 'scoped_association', '0.0.5'
|
14
19
|
|
15
20
|
And then execute:
|
16
21
|
|
@@ -36,6 +41,7 @@ class Post < ActiveRecord::Base
|
|
36
41
|
class_name: "Tag",
|
37
42
|
scoped: true
|
38
43
|
end
|
44
|
+
```
|
39
45
|
|
40
46
|
## Running tests
|
41
47
|
|
@@ -12,6 +12,29 @@ module ScopedAssociations
|
|
12
12
|
reflection
|
13
13
|
end
|
14
14
|
|
15
|
+
def initialize(model, name, scope, options)
|
16
|
+
super
|
17
|
+
if scoped?
|
18
|
+
search_scope = foreign_scope(model)
|
19
|
+
proc_scope = proc { where(search_scope => name) }
|
20
|
+
if @scope.nil?
|
21
|
+
@scope = proc { instance_eval(&proc_scope) }
|
22
|
+
else
|
23
|
+
old_scope = @scope
|
24
|
+
@scope = proc { instance_eval(&proc_scope)
|
25
|
+
.instance_eval(&old_scope) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def foreign_scope(model)
|
31
|
+
if options[:as]
|
32
|
+
"#{options[:as]}_scope"
|
33
|
+
else
|
34
|
+
model.name.underscore.demodulize + "_scope"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
15
38
|
private
|
16
39
|
|
17
40
|
def extend_reflection(reflection)
|
@@ -45,18 +68,9 @@ module ScopedAssociations
|
|
45
68
|
attributes[reflection.foreign_scope] = reflection.name.to_s
|
46
69
|
attributes
|
47
70
|
end
|
48
|
-
|
49
|
-
def association_scope
|
50
|
-
super.where(reflection.foreign_scope => reflection.name.to_s)
|
51
|
-
end
|
52
|
-
|
53
|
-
def target_scope
|
54
|
-
super.where(reflection.foreign_scope => reflection.name.to_s)
|
55
|
-
end
|
56
71
|
end
|
57
72
|
end
|
58
73
|
end
|
59
74
|
end
|
60
75
|
|
61
76
|
ActiveRecord::Associations::Builder::HasMany.send :include, ScopedAssociations::ActiveRecord4::HasMany
|
62
|
-
|
@@ -12,6 +12,29 @@ module ScopedAssociations
|
|
12
12
|
reflection
|
13
13
|
end
|
14
14
|
|
15
|
+
def initialize(model, name, scope, options)
|
16
|
+
super
|
17
|
+
if scoped?
|
18
|
+
search_scope = foreign_scope(model)
|
19
|
+
proc_scope = proc { where(search_scope => name) }
|
20
|
+
if @scope.nil?
|
21
|
+
@scope = proc { instance_eval(&proc_scope) }
|
22
|
+
else
|
23
|
+
old_scope = @scope
|
24
|
+
@scope = proc { instance_eval(&proc_scope)
|
25
|
+
.instance_eval(&old_scope) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def foreign_scope(model)
|
31
|
+
if options[:as]
|
32
|
+
"#{options[:as]}_scope"
|
33
|
+
else
|
34
|
+
model.name.underscore.demodulize + "_scope"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
15
38
|
private
|
16
39
|
|
17
40
|
def extend_reflection(reflection)
|
@@ -45,18 +68,9 @@ module ScopedAssociations
|
|
45
68
|
attributes[reflection.foreign_scope] = reflection.name.to_s
|
46
69
|
attributes
|
47
70
|
end
|
48
|
-
|
49
|
-
def association_scope
|
50
|
-
super.where(reflection.foreign_scope => reflection.name.to_s)
|
51
|
-
end
|
52
|
-
|
53
|
-
def target_scope
|
54
|
-
super.where(reflection.foreign_scope => reflection.name.to_s)
|
55
|
-
end
|
56
71
|
end
|
57
72
|
end
|
58
73
|
end
|
59
74
|
end
|
60
75
|
|
61
76
|
ActiveRecord::Associations::Builder::HasOne.send :include, ScopedAssociations::ActiveRecord4::HasOne
|
62
|
-
|
data/scoped_associations.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'scoped_associations/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'scoped_associations'
|
8
8
|
spec.version = ScopedAssociations::VERSION
|
9
|
-
spec.authors = ['Stefano Verna']
|
10
|
-
spec.email = ['stefano.verna@gmail.com']
|
9
|
+
spec.authors = ['Stefano Verna', 'David Librera']
|
10
|
+
spec.email = ['stefano.verna@gmail.com', "davidlibrera@gmail.com"]
|
11
11
|
spec.description = %q{ScopedAssociations lets you create multiple `has_to` and `has_many` associations between two ActiveRecord models.}
|
12
12
|
spec.summary = %q{Create multiple `has_to` and `has_many` associations between two ActiveRecord models}
|
13
13
|
spec.homepage = 'https://github.com/stefanoverna/scoped_associations'
|
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency 'rspec'
|
24
24
|
spec.add_development_dependency 'sqlite3'
|
25
25
|
spec.add_development_dependency 'coveralls'
|
26
|
+
spec.add_development_dependency 'database_cleaner'
|
26
27
|
|
27
28
|
spec.required_ruby_version = ">= 1.9.3"
|
28
29
|
|
29
|
-
spec.add_dependency 'activerecord', ['>=
|
30
|
+
spec.add_dependency 'activerecord', ['>= 4.0', '< 4.3']
|
30
31
|
spec.add_dependency 'activesupport'
|
31
32
|
end
|
32
|
-
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ScopedAssociations' do
|
4
|
+
let(:post) { Post.new(title: "A title") }
|
5
|
+
|
6
|
+
describe "polymorphic has_many" do
|
7
|
+
it "works with direct assignment" do
|
8
|
+
post.secondary_tags = [ Tag.new(name: "foo") ]
|
9
|
+
post.save!
|
10
|
+
|
11
|
+
post.reload
|
12
|
+
expect(post.secondary_tags).to be_present
|
13
|
+
expect(post.primary_tags).to be_blank
|
14
|
+
end
|
15
|
+
|
16
|
+
it "works with nested attributes" do
|
17
|
+
post = Post.new(primary_tags_attributes: [ { name: "foo" } ])
|
18
|
+
post.save!
|
19
|
+
post.reload
|
20
|
+
|
21
|
+
expect(post.primary_tags).to be_present
|
22
|
+
expect(post.secondary_tags).to be_blank
|
23
|
+
end
|
24
|
+
|
25
|
+
it "works with .build" do
|
26
|
+
post.secondary_tags.build(name: "foo")
|
27
|
+
post.save!
|
28
|
+
post.reload
|
29
|
+
|
30
|
+
expect(post.secondary_tags).to be_present
|
31
|
+
expect(post.primary_tags).to be_blank
|
32
|
+
end
|
33
|
+
|
34
|
+
it "works with .create" do
|
35
|
+
post.save!
|
36
|
+
post.secondary_tags.create(name: "foo")
|
37
|
+
|
38
|
+
post.reload
|
39
|
+
expect(post.secondary_tags).to be_present
|
40
|
+
expect(post.primary_tags).to be_blank
|
41
|
+
end
|
42
|
+
|
43
|
+
it "works with .joins" do
|
44
|
+
post.save!
|
45
|
+
post.primary_tags.create(name: "foo")
|
46
|
+
post.reload
|
47
|
+
|
48
|
+
expect(Post.joins(:primary_tags)).to be_present
|
49
|
+
expect(Post.joins(:secondary_tags)).to be_blank
|
50
|
+
end
|
51
|
+
|
52
|
+
it "works with <<" do
|
53
|
+
post.save
|
54
|
+
post.secondary_tags << Tag.new(name: "foo")
|
55
|
+
|
56
|
+
post.reload
|
57
|
+
expect(post.secondary_tags).to be_present
|
58
|
+
expect(post.primary_tags).to be_blank
|
59
|
+
end
|
60
|
+
|
61
|
+
it "works with additional scope" do
|
62
|
+
post.save!
|
63
|
+
|
64
|
+
post.active_tags.create(name: "foo")
|
65
|
+
post.primary_tags.create(name: "bar", active: false)
|
66
|
+
post.secondary_tags.create(name: "baz", active: true)
|
67
|
+
|
68
|
+
post.active_tags.update_all(active: false)
|
69
|
+
post.reload
|
70
|
+
|
71
|
+
expect(post.active_tags).to be_blank
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ScopedAssociations' do
|
4
|
+
let(:post) { Post.new(title: "A title") }
|
5
|
+
|
6
|
+
describe "not polymorphic has_many" do
|
7
|
+
it "works with direct assignment" do
|
8
|
+
post.secondary_comments = [ Comment.new(comment: "foo") ]
|
9
|
+
post.save!
|
10
|
+
|
11
|
+
post.reload
|
12
|
+
expect(post.secondary_comments).to be_present
|
13
|
+
expect(post.primary_comments).to be_blank
|
14
|
+
end
|
15
|
+
|
16
|
+
it "works with nested attributes" do
|
17
|
+
post = Post.new(primary_comments_attributes: [ { comment: "foo" } ])
|
18
|
+
post.save!
|
19
|
+
post.reload
|
20
|
+
|
21
|
+
expect(post.primary_comments).to be_present
|
22
|
+
expect(post.secondary_comments).to be_blank
|
23
|
+
end
|
24
|
+
|
25
|
+
it "works with .build" do
|
26
|
+
post.secondary_comments.build(comment: "foo")
|
27
|
+
post.save
|
28
|
+
|
29
|
+
post.reload
|
30
|
+
expect(post.secondary_comments).to be_present
|
31
|
+
expect(post.primary_comments).to be_blank
|
32
|
+
end
|
33
|
+
|
34
|
+
it "works with .create" do
|
35
|
+
post.save!
|
36
|
+
post.primary_comments.create(comment: "foo")
|
37
|
+
post.reload
|
38
|
+
|
39
|
+
expect(post.primary_comments).to be_present
|
40
|
+
expect(post.secondary_comments).to be_blank
|
41
|
+
end
|
42
|
+
|
43
|
+
it "works with .joins" do
|
44
|
+
post.save!
|
45
|
+
post.primary_comments.create(comment: "foo")
|
46
|
+
post.reload
|
47
|
+
|
48
|
+
expect(Post.joins(:primary_comments)).to be_present
|
49
|
+
expect(Post.joins(:secondary_comments)).to be_blank
|
50
|
+
end
|
51
|
+
|
52
|
+
it "works with <<" do
|
53
|
+
post.save
|
54
|
+
post.secondary_comments << Comment.new(comment: "foo")
|
55
|
+
|
56
|
+
post.reload
|
57
|
+
expect(post.secondary_comments).to be_present
|
58
|
+
expect(post.primary_comments).to be_blank
|
59
|
+
end
|
60
|
+
|
61
|
+
it "works with additional scope" do
|
62
|
+
post.save!
|
63
|
+
|
64
|
+
post.active_comments.create(comment: "foo")
|
65
|
+
post.primary_comments.create(comment: "bar", active: false)
|
66
|
+
post.secondary_comments.create(comment: "baz", active: true)
|
67
|
+
|
68
|
+
post.active_comments.update_all(active: false)
|
69
|
+
post.reload
|
70
|
+
|
71
|
+
expect(post.active_comments).to be_blank
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ScopedAssociations' do
|
4
|
+
let(:post) { Post.new(title: "A title") }
|
5
|
+
|
6
|
+
context "polymorphic has_one" do
|
7
|
+
|
8
|
+
it "works with direct assignment" do
|
9
|
+
post.secondary_tag = Tag.new(name: "foo")
|
10
|
+
post.save!
|
11
|
+
post.reload
|
12
|
+
|
13
|
+
expect(post.secondary_tag).to be_present
|
14
|
+
expect(post.primary_tag).to be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "works with nested attributes" do
|
18
|
+
post = Post.new(primary_tag_attributes: { name: "foo" })
|
19
|
+
post.save!
|
20
|
+
post.reload
|
21
|
+
|
22
|
+
expect(post.primary_tag).to be_present
|
23
|
+
expect(post.secondary_tag).to be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "works with .build" do
|
27
|
+
post.build_secondary_tag(name: "foo")
|
28
|
+
post.save!
|
29
|
+
post.reload
|
30
|
+
|
31
|
+
expect(post.secondary_tag).to be_present
|
32
|
+
expect(post.primary_tag).to be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it "works with .create" do
|
36
|
+
post.save!
|
37
|
+
post.create_secondary_tag(name: "foo")
|
38
|
+
post.reload
|
39
|
+
|
40
|
+
expect(post.secondary_tag).to be_present
|
41
|
+
expect(post.primary_tag).to be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "works with .joins" do
|
45
|
+
post.save!
|
46
|
+
post.create_secondary_tag(name: "foo")
|
47
|
+
|
48
|
+
expect(Post.joins(:primary_tag)).to be_blank
|
49
|
+
expect(Post.joins(:secondary_tag)).to be_present
|
50
|
+
end
|
51
|
+
|
52
|
+
it "works with additional scope" do
|
53
|
+
post.active_tag = Tag.new(name: "foo", active: false)
|
54
|
+
post.primary_tag = Tag.new(name: "bar", active: false)
|
55
|
+
post.secondary_tag = Tag.new(name: "baz", active: true)
|
56
|
+
|
57
|
+
post.save!
|
58
|
+
post.reload
|
59
|
+
|
60
|
+
expect(post.active_tag).to be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ScopedAssociations' do
|
4
|
+
let(:post) { Post.new(title: "A title") }
|
5
|
+
|
6
|
+
context "non polymorphic has_one" do
|
7
|
+
it "works with direct assignment" do
|
8
|
+
post.secondary_comment = Comment.new(comment: "foo")
|
9
|
+
post.save!
|
10
|
+
post.reload
|
11
|
+
|
12
|
+
expect(post.secondary_comment).to be_present
|
13
|
+
expect(post.primary_comment).to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "works with nested attributes" do
|
17
|
+
post = Post.new(primary_comment_attributes: { comment: "foo" })
|
18
|
+
post.save!
|
19
|
+
post.reload
|
20
|
+
|
21
|
+
expect(post.primary_comment).to be_present
|
22
|
+
expect(post.secondary_comment).to be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "works with .build" do
|
26
|
+
post.build_secondary_comment(comment: "foo")
|
27
|
+
post.save!
|
28
|
+
post.reload
|
29
|
+
|
30
|
+
expect(post.secondary_comment).to be_present
|
31
|
+
expect(post.primary_comment).to be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it "works with .create" do
|
35
|
+
post.save!
|
36
|
+
post.create_primary_comment(comment: "foo")
|
37
|
+
post.reload
|
38
|
+
|
39
|
+
expect(post.primary_comment).to be_present
|
40
|
+
expect(post.secondary_comment).to be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it "works with .joins" do
|
44
|
+
post.save!
|
45
|
+
post.create_secondary_comment(comment: "foo")
|
46
|
+
|
47
|
+
expect(Post.joins(:primary_comment)).to be_blank
|
48
|
+
expect(Post.joins(:secondary_comment)).to be_present
|
49
|
+
end
|
50
|
+
|
51
|
+
it "works with additional scope" do
|
52
|
+
post.active_comment = Comment.new(comment: "foo", active: false)
|
53
|
+
post.primary_comment = Comment.new(comment: "bar", active: false)
|
54
|
+
post.secondary_comment = Comment.new(comment: "baz", active: true)
|
55
|
+
post.save!
|
56
|
+
post.reload
|
57
|
+
|
58
|
+
expect(post.active_comment).to be_nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/spec/integration_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -3,12 +3,27 @@ require 'bundler'
|
|
3
3
|
require 'active_record'
|
4
4
|
require 'logger'
|
5
5
|
require 'coveralls'
|
6
|
+
require 'database_cleaner'
|
7
|
+
|
6
8
|
Coveralls.wear!
|
7
9
|
|
8
10
|
ROOT = File.expand_path('../', __FILE__)
|
9
11
|
|
10
12
|
require 'scoped_associations'
|
11
13
|
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.before(:suite) do
|
16
|
+
DatabaseCleaner.strategy = :transaction
|
17
|
+
DatabaseCleaner.clean_with(:truncation)
|
18
|
+
end
|
19
|
+
|
20
|
+
config.around(:each) do |example|
|
21
|
+
DatabaseCleaner.cleaning do
|
22
|
+
example.run
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
12
27
|
ActiveRecord::Base.establish_connection(
|
13
28
|
adapter: "sqlite3",
|
14
29
|
database: ":memory:"
|
@@ -22,6 +37,7 @@ ActiveRecord::Schema.define do
|
|
22
37
|
t.string :owner_type, null: false
|
23
38
|
t.string :owner_scope, null: false
|
24
39
|
t.string :name, null: false
|
40
|
+
t.boolean :active, null: false, default: false
|
25
41
|
end
|
26
42
|
|
27
43
|
create_table :posts do |t|
|
@@ -32,11 +48,10 @@ ActiveRecord::Schema.define do
|
|
32
48
|
t.integer :post_id, null: false
|
33
49
|
t.string :post_scope, null: false
|
34
50
|
t.string :comment, null: false
|
51
|
+
t.boolean :active, null: false, default: false
|
35
52
|
end
|
36
53
|
end
|
37
54
|
|
38
|
-
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
39
|
-
|
40
55
|
class Comment < ActiveRecord::Base
|
41
56
|
belongs_to :post
|
42
57
|
end
|
@@ -47,40 +62,70 @@ end
|
|
47
62
|
|
48
63
|
class Post < ActiveRecord::Base
|
49
64
|
has_one :primary_tag, as: :owner,
|
50
|
-
|
51
|
-
|
65
|
+
class_name: "Tag",
|
66
|
+
scoped: true
|
52
67
|
|
53
68
|
accepts_nested_attributes_for :primary_tag
|
54
69
|
|
70
|
+
has_one :active_tag,
|
71
|
+
-> { where(active: true) },
|
72
|
+
as: :owner,
|
73
|
+
class_name: "Tag",
|
74
|
+
scoped: true
|
75
|
+
|
76
|
+
|
77
|
+
|
55
78
|
has_one :secondary_tag, as: :owner,
|
56
|
-
|
57
|
-
|
79
|
+
class_name: "Tag",
|
80
|
+
scoped: true
|
58
81
|
|
59
82
|
has_many :primary_tags, as: :owner,
|
60
|
-
|
61
|
-
|
83
|
+
class_name: "Tag",
|
84
|
+
scoped: true
|
62
85
|
|
63
86
|
accepts_nested_attributes_for :primary_tags
|
64
87
|
|
65
|
-
has_many :
|
66
|
-
|
67
|
-
|
88
|
+
has_many :active_tags,
|
89
|
+
-> { where(active: true) },
|
90
|
+
as: :owner,
|
91
|
+
class_name: "Tag",
|
92
|
+
scoped: true
|
93
|
+
|
94
|
+
|
95
|
+
has_many :secondary_tags,
|
96
|
+
as: :owner,
|
97
|
+
class_name: "Tag",
|
98
|
+
scoped: true
|
68
99
|
|
100
|
+
has_many :comments
|
69
101
|
|
70
|
-
has_one :primary_comment,
|
71
|
-
|
102
|
+
has_one :primary_comment,
|
103
|
+
class_name: "Comment",
|
104
|
+
scoped: true
|
105
|
+
|
106
|
+
has_one :active_comment,
|
107
|
+
-> { where(active: true) },
|
108
|
+
class_name: "Comment",
|
109
|
+
scoped: true
|
72
110
|
|
73
111
|
accepts_nested_attributes_for :primary_comment
|
74
112
|
|
75
|
-
has_one :secondary_comment,
|
76
|
-
|
113
|
+
has_one :secondary_comment,
|
114
|
+
class_name: "Comment",
|
115
|
+
scoped: true
|
116
|
+
|
117
|
+
has_many :primary_comments,
|
118
|
+
class_name: "Comment",
|
119
|
+
scoped: true
|
77
120
|
|
78
|
-
has_many :
|
79
|
-
|
121
|
+
has_many :active_comments,
|
122
|
+
-> { where(active: true) },
|
123
|
+
class_name: "Comment",
|
124
|
+
scoped: true
|
80
125
|
|
81
126
|
accepts_nested_attributes_for :primary_comments
|
82
127
|
|
83
|
-
has_many :secondary_comments,
|
84
|
-
|
128
|
+
has_many :secondary_comments,
|
129
|
+
class_name: "Comment",
|
130
|
+
scoped: true
|
85
131
|
end
|
86
|
-
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scoped_associations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefano Verna
|
8
|
+
- David Librera
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2016-01-26 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
@@ -80,13 +81,27 @@ dependencies:
|
|
80
81
|
- - ">="
|
81
82
|
- !ruby/object:Gem::Version
|
82
83
|
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: database_cleaner
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
83
98
|
- !ruby/object:Gem::Dependency
|
84
99
|
name: activerecord
|
85
100
|
requirement: !ruby/object:Gem::Requirement
|
86
101
|
requirements:
|
87
102
|
- - ">="
|
88
103
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
104
|
+
version: '4.0'
|
90
105
|
- - "<"
|
91
106
|
- !ruby/object:Gem::Version
|
92
107
|
version: '4.3'
|
@@ -96,7 +111,7 @@ dependencies:
|
|
96
111
|
requirements:
|
97
112
|
- - ">="
|
98
113
|
- !ruby/object:Gem::Version
|
99
|
-
version: '
|
114
|
+
version: '4.0'
|
100
115
|
- - "<"
|
101
116
|
- !ruby/object:Gem::Version
|
102
117
|
version: '4.3'
|
@@ -118,28 +133,31 @@ description: ScopedAssociations lets you create multiple `has_to` and `has_many`
|
|
118
133
|
between two ActiveRecord models.
|
119
134
|
email:
|
120
135
|
- stefano.verna@gmail.com
|
136
|
+
- davidlibrera@gmail.com
|
121
137
|
executables: []
|
122
138
|
extensions: []
|
123
139
|
extra_rdoc_files: []
|
124
140
|
files:
|
125
141
|
- ".gitignore"
|
142
|
+
- ".rspec"
|
126
143
|
- ".travis.yml"
|
127
144
|
- Appraisals
|
128
145
|
- Gemfile
|
129
146
|
- LICENSE.txt
|
130
147
|
- README.md
|
131
148
|
- Rakefile
|
132
|
-
- gemfiles/activerecord30.gemfile
|
133
149
|
- gemfiles/activerecord40.gemfile
|
134
150
|
- gemfiles/activerecord41.gemfile
|
135
151
|
- gemfiles/activerecord42.gemfile
|
136
152
|
- lib/scoped_associations.rb
|
137
|
-
- lib/scoped_associations/activerecord3/has_many.rb
|
138
|
-
- lib/scoped_associations/activerecord3/has_one.rb
|
139
153
|
- lib/scoped_associations/activerecord4/has_many.rb
|
140
154
|
- lib/scoped_associations/activerecord4/has_one.rb
|
141
155
|
- lib/scoped_associations/version.rb
|
142
156
|
- scoped_associations.gemspec
|
157
|
+
- spec/has_many_polymorphic_spec.rb
|
158
|
+
- spec/has_many_spec.rb
|
159
|
+
- spec/has_one_polymorphic_spec.rb
|
160
|
+
- spec/has_one_spec.rb
|
143
161
|
- spec/integration_spec.rb
|
144
162
|
- spec/spec_helper.rb
|
145
163
|
homepage: https://github.com/stefanoverna/scoped_associations
|
@@ -168,5 +186,9 @@ specification_version: 4
|
|
168
186
|
summary: Create multiple `has_to` and `has_many` associations between two ActiveRecord
|
169
187
|
models
|
170
188
|
test_files:
|
189
|
+
- spec/has_many_polymorphic_spec.rb
|
190
|
+
- spec/has_many_spec.rb
|
191
|
+
- spec/has_one_polymorphic_spec.rb
|
192
|
+
- spec/has_one_spec.rb
|
171
193
|
- spec/integration_spec.rb
|
172
194
|
- spec/spec_helper.rb
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
|
-
module ScopedAssociations
|
4
|
-
module ActiveRecord3
|
5
|
-
module HasMany
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
included do |klass|
|
9
|
-
klass.valid_options += [:scoped]
|
10
|
-
end
|
11
|
-
|
12
|
-
def build
|
13
|
-
reflection = super
|
14
|
-
extend_reflection(reflection)
|
15
|
-
reflection
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def extend_reflection(reflection)
|
21
|
-
if scoped?
|
22
|
-
reflection.extend ReflectionExtension
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def scoped?
|
27
|
-
options[:scoped]
|
28
|
-
end
|
29
|
-
|
30
|
-
module ReflectionExtension
|
31
|
-
def foreign_scope
|
32
|
-
if options[:as]
|
33
|
-
"#{options[:as]}_scope"
|
34
|
-
else
|
35
|
-
name = active_record.name
|
36
|
-
name.underscore.demodulize + "_scope"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def association_class
|
41
|
-
ScopedHasManyAssociation
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class ScopedHasManyAssociation < ActiveRecord::Associations::HasManyAssociation
|
46
|
-
def creation_attributes
|
47
|
-
attributes = super
|
48
|
-
attributes[reflection.foreign_scope] = reflection.name.to_s
|
49
|
-
attributes
|
50
|
-
end
|
51
|
-
|
52
|
-
def association_scope
|
53
|
-
super.where(reflection.foreign_scope => reflection.name.to_s)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
ActiveRecord::Associations::Builder::HasMany.send :include, ScopedAssociations::ActiveRecord3::HasMany
|
62
|
-
|
63
|
-
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
|
-
module ScopedAssociations
|
4
|
-
module ActiveRecord3
|
5
|
-
module HasOne
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
included do |klass|
|
9
|
-
klass.valid_options += [:scoped]
|
10
|
-
end
|
11
|
-
|
12
|
-
def build
|
13
|
-
reflection = super
|
14
|
-
extend_reflection(reflection)
|
15
|
-
reflection
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def extend_reflection(reflection)
|
21
|
-
if scoped?
|
22
|
-
reflection.extend ReflectionExtension
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def scoped?
|
27
|
-
options[:scoped]
|
28
|
-
end
|
29
|
-
|
30
|
-
module ReflectionExtension
|
31
|
-
def foreign_scope
|
32
|
-
if options[:as]
|
33
|
-
"#{options[:as]}_scope"
|
34
|
-
else
|
35
|
-
name = active_record.name
|
36
|
-
name.underscore.demodulize + "_scope"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def association_class
|
41
|
-
ScopedHasOneAssociation
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class ScopedHasOneAssociation < ActiveRecord::Associations::HasOneAssociation
|
46
|
-
def creation_attributes
|
47
|
-
attributes = super
|
48
|
-
attributes[reflection.foreign_scope] = reflection.name.to_s
|
49
|
-
attributes
|
50
|
-
end
|
51
|
-
|
52
|
-
def association_scope
|
53
|
-
super.where(reflection.foreign_scope => reflection.name.to_s)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
ActiveRecord::Associations::Builder::HasOne.send :include, ScopedAssociations::ActiveRecord3::HasOne
|
62
|
-
|
63
|
-
|
64
|
-
|