remockable 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/LICENSE +1 -1
- data/README.markdown +50 -36
- data/Rakefile +1 -0
- data/lib/remockable/active_model/helpers.rb +2 -0
- data/lib/remockable/active_record/helpers.rb +2 -0
- data/lib/remockable/version.rb +1 -1
- data/remockable.gemspec +23 -0
- data/spec/active_model/allow_mass_assignment_of_spec.rb +86 -0
- data/spec/active_model/allow_values_for_spec.rb +46 -0
- data/spec/active_model/validate_acceptance_of_spec.rb +16 -0
- data/spec/active_model/validate_confirmation_of_spec.rb +14 -0
- data/spec/active_model/validate_exclusion_of_spec.rb +16 -0
- data/spec/active_model/validate_format_of_spec.rb +18 -0
- data/spec/active_model/validate_inclusion_of_spec.rb +16 -0
- data/spec/active_model/validate_length_of_spec.rb +26 -0
- data/spec/active_model/validate_numericality_of_spec.rb +23 -0
- data/spec/active_model/validate_presence_of_spec.rb +14 -0
- data/spec/active_record/accept_nested_attributes_for_spec.rb +47 -0
- data/spec/active_record/belong_to_spec.rb +62 -0
- data/spec/active_record/have_and_belong_to_many_spec.rb +67 -0
- data/spec/active_record/have_column_spec.rb +109 -0
- data/spec/active_record/have_default_scope_spec.rb +169 -0
- data/spec/active_record/have_index_spec.rb +89 -0
- data/spec/active_record/have_many_spec.rb +70 -0
- data/spec/active_record/have_one_spec.rb +61 -0
- data/spec/active_record/have_scope_spec.rb +229 -0
- data/spec/active_record/validate_associated_spec.rb +27 -0
- data/spec/active_record/validate_uniqueness_of_spec.rb +23 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/active_record_example_group.rb +22 -0
- data/spec/support/class_builder.rb +39 -0
- data/spec/support/shared/a_validation_matcher.rb +130 -0
- data/spec/support/shared/an_active_record_matcher.rb +53 -0
- metadata +134 -40
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :have_column do
|
4
|
+
let(:options) { :one }
|
5
|
+
|
6
|
+
it_behaves_like 'an Active Record matcher' do
|
7
|
+
let(:model) { build_class(:User, ActiveRecord::Base) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
create_table(:users) { |table| }
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { model.new }
|
14
|
+
|
15
|
+
context 'description' do
|
16
|
+
let(:matcher) { send(matcher_name, *options) }
|
17
|
+
|
18
|
+
it 'has a custom description' do
|
19
|
+
name = matcher.instance_variable_get(:@name).to_s.gsub(/_/, ' ')
|
20
|
+
with = " with #{matcher.expected}" if matcher.expected.any?
|
21
|
+
|
22
|
+
matcher.description.should == "#{name} #{options}#{with}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with a column' do
|
27
|
+
it 'matches if the column exists' do
|
28
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :string)
|
29
|
+
model.should have_column(:one)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does not match if the column does not exist' do
|
33
|
+
model.should_not have_column(:one)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with option :default' do
|
38
|
+
it 'matches if the column exists' do
|
39
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :integer, :default => 1)
|
40
|
+
model.should have_column(:one, :default => 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not match if the column does not have the same default' do
|
44
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :integer, :default => 2)
|
45
|
+
model.should_not have_column(:one, :default => 1)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with option :limit' do
|
50
|
+
it 'matches if the column exists' do
|
51
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :string, :limit => 10)
|
52
|
+
model.should have_column(:one, :limit => 10)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'does not match if the column does not have the same limit' do
|
56
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :string, :limit => 5)
|
57
|
+
model.should_not have_column(:one, :limit => 10)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with option :null' do
|
62
|
+
it 'matches if the column exists' do
|
63
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :integer, :null => false, :default => 1)
|
64
|
+
model.should have_column(:one, :null => false)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'does not match if the column does not have the same null' do
|
68
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :integer)
|
69
|
+
model.should_not have_column(:one, :null => false)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with option :precision' do
|
74
|
+
it 'matches if the column exists' do
|
75
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :decimal, :precision => 8)
|
76
|
+
model.should have_column(:one, :precision => 8)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'does not match if the column does not have the same null' do
|
80
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :decimal, :precision => 8)
|
81
|
+
model.should_not have_column(:one, :precision => 5)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with option :scale' do
|
86
|
+
it 'matches if the column exists' do
|
87
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :decimal, :precision => 8, :scale => 2)
|
88
|
+
model.should have_column(:one, :scale => 2)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'does not match if the column does not have the same null' do
|
92
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :decimal, :precision => 8, :scale => 2)
|
93
|
+
model.should_not have_column(:one, :scale => 3)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'with option :type' do
|
98
|
+
it 'matches if the column exists' do
|
99
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :integer)
|
100
|
+
model.should have_column(:one, :type => :integer)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'does not match if the column does not have the same type' do
|
104
|
+
ActiveRecord::Base.connection.add_column(:users, :one, :string)
|
105
|
+
model.should_not have_column(:one, :type => :integer)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :have_default_scope do
|
4
|
+
let(:options) { :one }
|
5
|
+
|
6
|
+
it_behaves_like 'an Active Record matcher' do
|
7
|
+
let(:model) { build_class(:User, ActiveRecord::Base) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
create_table(:users) { |table| table.string(:one) }
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { model.new }
|
14
|
+
|
15
|
+
context 'description' do
|
16
|
+
let(:matcher) { send(matcher_name, *options) }
|
17
|
+
|
18
|
+
it 'has a custom description' do
|
19
|
+
name = matcher.instance_variable_get(:@name).to_s.gsub(/_/, ' ')
|
20
|
+
with = " with #{matcher.expected}" if matcher.expected.any?
|
21
|
+
|
22
|
+
matcher.description.should == "have a default scope#{with}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'without arguments' do
|
27
|
+
it 'matches if a default scope exists' do
|
28
|
+
model.instance_eval { default_scope(order(:id)) }
|
29
|
+
model.should have_default_scope
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does not match if a default scope does not exist' do
|
33
|
+
model.should_not have_default_scope
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with a from value' do
|
38
|
+
it 'matches if the scope exists and the query matches' do
|
39
|
+
model.instance_eval { default_scope(from('users')) }
|
40
|
+
model.should have_default_scope.from('users')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not match if the query does not match' do
|
44
|
+
model.instance_eval { default_scope(from('users')) }
|
45
|
+
model.should_not have_default_scope.from('friends')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with a group value' do
|
50
|
+
it 'matches if the scope exists and the query matches' do
|
51
|
+
model.instance_eval { default_scope(group('one')) }
|
52
|
+
model.should have_default_scope.group('one')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'does not match if the query does not match' do
|
56
|
+
model.instance_eval { default_scope(group('one')) }
|
57
|
+
model.should_not have_default_scope.group('two')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with a having value' do
|
62
|
+
it 'matches if the scope exists and the query matches' do
|
63
|
+
model.instance_eval { default_scope(having('COUNT(*) > 1')) }
|
64
|
+
model.should have_default_scope.having('COUNT(*) > 1')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'does not match if the query does not match' do
|
68
|
+
model.instance_eval { default_scope(having('COUNT(*) > 1')) }
|
69
|
+
model.should_not have_default_scope.having('COUNT(*) > 2')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with a having value' do
|
74
|
+
it 'matches if the scope exists and the query matches' do
|
75
|
+
model.instance_eval { default_scope(having('COUNT(*) > 1')) }
|
76
|
+
model.should have_default_scope.having('COUNT(*) > 1')
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'does not match if the query does not match' do
|
80
|
+
model.instance_eval { default_scope(having('COUNT(*) > 1')) }
|
81
|
+
model.should_not have_default_scope.having('COUNT(*) > 2')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with a joins value' do
|
86
|
+
it 'matches if the scope exists and the query matches' do
|
87
|
+
model.instance_eval { default_scope(joins('INNER JOIN friends')) }
|
88
|
+
model.should have_default_scope.joins('INNER JOIN friends')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'does not match if the query does not match' do
|
92
|
+
model.instance_eval { default_scope(joins('INNER JOIN friends')) }
|
93
|
+
model.should_not have_default_scope.joins('INNER JOIN enemies')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'with a limit value' do
|
98
|
+
it 'matches if the scope exists and the query matches' do
|
99
|
+
model.instance_eval { default_scope(limit(10)) }
|
100
|
+
model.should have_default_scope.limit(10)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'does not match if the query does not match' do
|
104
|
+
model.instance_eval { default_scope(limit(10)) }
|
105
|
+
model.should_not have_default_scope.limit(15)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'with an offset value' do
|
110
|
+
it 'matches if the scope exists and the query matches' do
|
111
|
+
model.instance_eval { default_scope(offset(10)) }
|
112
|
+
model.should have_default_scope.offset(10)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'does not match if the query does not match' do
|
116
|
+
model.instance_eval { default_scope(offset(10)) }
|
117
|
+
model.should_not have_default_scope.offset(15)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'with an order value' do
|
122
|
+
it 'matches if the scope exists and the query matches' do
|
123
|
+
model.instance_eval { default_scope(order('one')) }
|
124
|
+
model.should have_default_scope.order('one')
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'does not match if the query does not match' do
|
128
|
+
model.instance_eval { default_scope(order('one')) }
|
129
|
+
model.should_not have_default_scope.order('id')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'with a reorder value' do
|
134
|
+
it 'matches if the scope exists and the query matches' do
|
135
|
+
model.instance_eval { default_scope(reorder('one')) }
|
136
|
+
model.should have_default_scope.reorder('one')
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'does not match if the query does not match' do
|
140
|
+
model.instance_eval { default_scope(reorder('one')) }
|
141
|
+
model.should_not have_default_scope.reorder('id')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'with a select value' do
|
146
|
+
it 'matches if the scope exists and the query matches' do
|
147
|
+
model.instance_eval { default_scope(select('one')) }
|
148
|
+
model.should have_default_scope.select('one')
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'does not match if the query does not match' do
|
152
|
+
model.instance_eval { default_scope(select('one')) }
|
153
|
+
model.should_not have_default_scope.select('id')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'with a where value' do
|
158
|
+
it 'matches if the scope exists and the query matches' do
|
159
|
+
model.instance_eval { default_scope(where(:one => nil)) }
|
160
|
+
model.should have_default_scope.where(:one => nil)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'does not match if the query does not match' do
|
164
|
+
model.instance_eval { default_scope(where(:one => nil)) }
|
165
|
+
model.should_not have_default_scope.where(:one => 1)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :have_index do
|
4
|
+
let(:options) { :one }
|
5
|
+
|
6
|
+
it_behaves_like 'an Active Record matcher' do
|
7
|
+
let(:model) { build_class(:User, ActiveRecord::Base) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
create_table(:users) do |table|
|
11
|
+
table.string(:one)
|
12
|
+
table.string(:two)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
subject { model.new }
|
17
|
+
|
18
|
+
context 'description' do
|
19
|
+
let(:matcher) { send(matcher_name, *options) }
|
20
|
+
|
21
|
+
it 'has a custom description' do
|
22
|
+
name = matcher.instance_variable_get(:@name).to_s.gsub(/_/, ' ')
|
23
|
+
with = " with #{matcher.expected}" if matcher.expected.any?
|
24
|
+
|
25
|
+
matcher.description.should == "#{name} on #{options}#{with}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with a single column' do
|
30
|
+
it 'matches if the index exists' do
|
31
|
+
ActiveRecord::Base.connection.add_index(:users, :one)
|
32
|
+
model.should have_index(:one)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'does not match if the index does not exist' do
|
36
|
+
model.should_not have_index(:one)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with multiple columns' do
|
41
|
+
it 'matches if the index exists' do
|
42
|
+
ActiveRecord::Base.connection.add_index(:users, [:one, :two])
|
43
|
+
model.should have_index([:one, :two])
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'does not match if the index does not exist' do
|
47
|
+
model.should_not have_index([:one, :two])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with option :unique' do
|
52
|
+
it 'matches if the index exists' do
|
53
|
+
ActiveRecord::Base.connection.add_index(:users, :one, :unique => true)
|
54
|
+
model.should have_index(:one, :unique => true)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'does not match if the index is not unique' do
|
58
|
+
ActiveRecord::Base.connection.add_index(:users, :one)
|
59
|
+
model.should_not have_index(:one, :unique => true)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'does not match if the index does not exist' do
|
63
|
+
model.should_not have_index(:one, :unique => true)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with option :name' do
|
68
|
+
it 'matches if the index exists' do
|
69
|
+
ActiveRecord::Base.connection.add_index(:users, :one, :name => :oneness)
|
70
|
+
model.should have_index(:one, :name => :oneness)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'does not match if the index does not exist' do
|
74
|
+
model.should_not have_index(:one, :name => :oneness)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with option :name and without :one' do
|
79
|
+
it 'matches if the index exists' do
|
80
|
+
ActiveRecord::Base.connection.add_index(:users, :one, :name => :oneness)
|
81
|
+
model.should have_index(:name => :oneness)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'does not match if the index does not exist' do
|
85
|
+
model.should_not have_index(:name => :oneness)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :have_many do
|
4
|
+
let(:macro) { :has_many }
|
5
|
+
let(:options) { [:posts, { :dependent => :destroy }] }
|
6
|
+
|
7
|
+
it_behaves_like 'an Active Record matcher' do
|
8
|
+
let(:model) { build_class(:User, ActiveRecord::Base) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
create_table(:users) { |table| table.string(:name) }
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { model.new }
|
15
|
+
|
16
|
+
context 'description' do
|
17
|
+
let(:matcher) { send(matcher_name, *options) }
|
18
|
+
|
19
|
+
it 'has a custom description' do
|
20
|
+
association = matcher.instance_variable_get(:@association)
|
21
|
+
with = " with #{matcher.expected.inspect}" if matcher.expected.any?
|
22
|
+
matcher.description.should == "have many #{association}#{with}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with no options' do
|
27
|
+
let(:options) { :posts }
|
28
|
+
|
29
|
+
it 'matches if the association exists' do
|
30
|
+
model.has_many(*options)
|
31
|
+
model.should have_many(*options)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not match if the association does not exist' do
|
35
|
+
model.should_not have_many(*options)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not match if the association is of the wrong type' do
|
39
|
+
model.belongs_to(*options)
|
40
|
+
model.should_not have_many(*options)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
with_option(:class_name, 'Post', 'Blog')
|
45
|
+
with_option(:conditions, { :published => true }, { :published => false })
|
46
|
+
with_option(:order, %w(published_at), %w(title))
|
47
|
+
with_option(:foreign_key, :post_id, :blog_id)
|
48
|
+
with_option(:primary_key, :id, :post_id)
|
49
|
+
with_option(:dependent, :destroy, :nullify)
|
50
|
+
with_option(:finder_sql, 'SELECT * FROM posts', 'SELECT * FROM blogs')
|
51
|
+
with_option(:counter_sql, 'SELECT COUNT(*) FROM posts', 'SELECT COUNT(*) FROM blogs')
|
52
|
+
with_option(:include, :comments, :trackbacks)
|
53
|
+
with_option(:group, 'comments_count', 'trackbacks_count')
|
54
|
+
with_option(:having, 'comments_count > 5', 'trackbacks_count > 5')
|
55
|
+
with_option(:limit, 5, 10)
|
56
|
+
with_option(:offset, 10, 20)
|
57
|
+
with_option(:select, %w(id), %w(title))
|
58
|
+
with_option(:as, :postable, :bloggable)
|
59
|
+
with_option(:through, :postings, :bloggings)
|
60
|
+
with_option(:source, :piece, :work)
|
61
|
+
with_option(:source_type, 'Post', 'Blog')
|
62
|
+
with_option(:uniq, true, false)
|
63
|
+
with_option(:readonly, true, false)
|
64
|
+
with_option(:validate, true, false)
|
65
|
+
with_option(:autosave, true, false)
|
66
|
+
with_option(:inverse_of, :users, :employees)
|
67
|
+
|
68
|
+
with_unsupported_option(:extend, Module.new)
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :have_one do
|
4
|
+
let(:macro) { :has_one }
|
5
|
+
let(:options) { [:address, { :dependent => :destroy }] }
|
6
|
+
|
7
|
+
it_behaves_like 'an Active Record matcher' do
|
8
|
+
let(:model) { build_class(:User, ActiveRecord::Base) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
create_table(:users) { |table| table.string(:name) }
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { model.new }
|
15
|
+
|
16
|
+
context 'description' do
|
17
|
+
let(:matcher) { send(matcher_name, *options) }
|
18
|
+
|
19
|
+
it 'has a custom description' do
|
20
|
+
association = matcher.instance_variable_get(:@association)
|
21
|
+
with = " with #{matcher.expected.inspect}" if matcher.expected.any?
|
22
|
+
matcher.description.should == "have a #{association}#{with}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with no options' do
|
27
|
+
let(:options) { :address }
|
28
|
+
|
29
|
+
it 'matches if the association exists' do
|
30
|
+
model.has_one(*options)
|
31
|
+
model.should have_one(*options)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not match if the association does not exist' do
|
35
|
+
model.should_not have_one(*options)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not match if the association is of the wrong type' do
|
39
|
+
model.has_many(*options)
|
40
|
+
model.should_not have_one(*options)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
with_option(:class_name, 'Address', 'Location')
|
45
|
+
with_option(:conditions, { :id => 1 }, { :id => 2 })
|
46
|
+
with_option(:order, %w(id), %w(name))
|
47
|
+
with_option(:dependent, :destroy, :nullify)
|
48
|
+
with_option(:foreign_key, :address_id, :location_id)
|
49
|
+
with_option(:primary_key, :id, :address_id)
|
50
|
+
with_option(:include, :country, :state)
|
51
|
+
with_option(:as, :addressable, :locatable)
|
52
|
+
with_option(:select, %w(id), %w(name))
|
53
|
+
with_option(:through, :offices, :locations)
|
54
|
+
with_option(:readonly, true, false)
|
55
|
+
with_option(:validate, true, false)
|
56
|
+
with_option(:autosave, true, false)
|
57
|
+
with_option(:inverse_of, :user, :employee)
|
58
|
+
|
59
|
+
with_unsupported_option(:extend, Module.new)
|
60
|
+
end
|
61
|
+
end
|