composite_primary_keys 14.0.9 → 14.0.10

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +10 -0
  3. data/README.rdoc +182 -182
  4. data/Rakefile +37 -37
  5. data/lib/composite_primary_keys/associations/collection_association.rb +38 -38
  6. data/lib/composite_primary_keys/associations/preloader/association.rb +52 -52
  7. data/lib/composite_primary_keys/autosave_association.rb +60 -60
  8. data/lib/composite_primary_keys/composite_arrays.rb +88 -88
  9. data/lib/composite_primary_keys/composite_predicates.rb +121 -121
  10. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +36 -36
  11. data/lib/composite_primary_keys/core.rb +71 -48
  12. data/lib/composite_primary_keys/persistence.rb +96 -96
  13. data/lib/composite_primary_keys/reflection.rb +93 -91
  14. data/lib/composite_primary_keys/relation/calculations.rb +110 -110
  15. data/lib/composite_primary_keys/relation/query_methods.rb +40 -40
  16. data/lib/composite_primary_keys/relation.rb +199 -199
  17. data/lib/composite_primary_keys/validations/uniqueness.rb +40 -40
  18. data/lib/composite_primary_keys/version.rb +1 -1
  19. data/lib/composite_primary_keys.rb +117 -117
  20. data/scripts/console.rb +48 -48
  21. data/tasks/databases/trilogy.rake +23 -23
  22. data/test/abstract_unit.rb +124 -124
  23. data/test/connections/databases.ci.yml +32 -32
  24. data/test/fixtures/admin.rb +4 -4
  25. data/test/fixtures/db_definitions/db2-create-tables.sql +146 -146
  26. data/test/fixtures/db_definitions/db2-drop-tables.sql +23 -23
  27. data/test/fixtures/db_definitions/mysql.sql +203 -203
  28. data/test/fixtures/db_definitions/oracle.drop.sql +45 -45
  29. data/test/fixtures/db_definitions/oracle.sql +220 -220
  30. data/test/fixtures/db_definitions/postgresql.sql +205 -205
  31. data/test/fixtures/db_definitions/sqlite.sql +190 -190
  32. data/test/fixtures/db_definitions/sqlserver.sql +199 -199
  33. data/test/fixtures/department.rb +20 -20
  34. data/test/fixtures/moderator.rb +4 -4
  35. data/test/fixtures/room.rb +14 -14
  36. data/test/fixtures/room_assignment.rb +18 -18
  37. data/test/fixtures/staff_room.rb +6 -6
  38. data/test/fixtures/staff_room_key.rb +6 -6
  39. data/test/fixtures/user.rb +14 -14
  40. data/test/test_associations.rb +403 -403
  41. data/test/test_composite_arrays.rb +44 -44
  42. data/test/test_equal.rb +55 -26
  43. data/test/test_has_one_through.rb +30 -30
  44. data/test/test_hash.rb +73 -0
  45. data/test/test_nested_attributes.rb +90 -90
  46. metadata +7 -8
@@ -1,200 +1,200 @@
1
- USE [composite_primary_keys_unittest];
2
-
3
- CREATE TABLE reference_types (
4
- reference_type_id [int] IDENTITY(1000,1) NOT NULL,
5
- type_label [varchar](50) NULL,
6
- abbreviation [varchar](50) NULL,
7
- description [varchar](50) NULL
8
- );
9
-
10
- CREATE TABLE reference_codes (
11
- reference_type_id [int],
12
- reference_code [int],
13
- code_label [varchar](50) NULL,
14
- abbreviation [varchar](50) NULL,
15
- description [varchar](50) NULL
16
- );
17
-
18
- CREATE TABLE products (
19
- id [int] IDENTITY(1000,1) NOT NULL,
20
- name [varchar](50) NULL
21
- );
22
-
23
- CREATE TABLE tariffs (
24
- [tariff_id] [int],
25
- [start_date] [date],
26
- [amount] [int] NULL,
27
- [created_at] [datetimeoffset](7) NOT NULL,
28
- [updated_at] [datetimeoffset](7) NOT NULL
29
- CONSTRAINT [tariffs_pk] PRIMARY KEY
30
- ( [tariff_id], [start_date] )
31
- );
32
-
33
- CREATE TABLE product_tariffs (
34
- [product_id] [int],
35
- [tariff_id] [int],
36
- [tariff_start_date] [date]
37
- CONSTRAINT [product_tariffs_pk] PRIMARY KEY
38
- ( [product_id], [tariff_id], [tariff_start_date] )
39
- );
40
-
41
- CREATE TABLE suburbs (
42
- city_id [int],
43
- suburb_id [int],
44
- name varchar(50) not null,
45
- CONSTRAINT [suburbs_pk] PRIMARY KEY
46
- ( [city_id], [suburb_id] )
47
- );
48
-
49
- CREATE TABLE streets (
50
- id [int] IDENTITY(1000,1) NOT NULL,
51
- city_id [int] NOT NULL,
52
- suburb_id [int] NOT NULL,
53
- name [varchar](50) NOT NULL
54
- );
55
-
56
- CREATE TABLE users (
57
- id [int] IDENTITY(1000,1) NOT NULL,
58
- name varchar(50) NOT NULL
59
- );
60
-
61
- CREATE TABLE moderators (
62
- id [int] PRIMARY KEY
63
- );
64
-
65
- CREATE TABLE admins (
66
- id [int] PRIMARY KEY
67
- );
68
-
69
- CREATE TABLE articles (
70
- id [int] IDENTITY(1000,1) NOT NULL,
71
- name varchar(50) NOT NULL
72
- );
73
-
74
- CREATE TABLE readings (
75
- id [int] PRIMARY KEY,
76
- user_id [int] NOT NULL,
77
- article_id [int] NOT NULL,
78
- rating [int] NOT NULL
79
- );
80
-
81
- CREATE TABLE groups (
82
- id [int] IDENTITY(1000,1) NOT NULL,
83
- name [varchar](50) NOT NULL
84
- );
85
-
86
- CREATE TABLE memberships (
87
- user_id [int] NOT NULL,
88
- group_id [int] NOT NULL
89
- CONSTRAINT [memberships_pk] PRIMARY KEY
90
- ( [user_id], [group_id] )
91
- );
92
-
93
- CREATE TABLE membership_statuses (
94
- id [int] IDENTITY(1,1) NOT NULL,
95
- user_id [int] not null,
96
- group_id [int] not null,
97
- status varchar(50) not null
98
- );
99
-
100
- CREATE TABLE departments (
101
- id [int] IDENTITY(100,1) NOT NULL,
102
- location_id [int] NOT NULL
103
- CONSTRAINT [departments_pk] PRIMARY KEY
104
- ( [id], [location_id] )
105
- );
106
-
107
- CREATE TABLE employees (
108
- id [int] IDENTITY(1000,1) NOT NULL,
109
- department_id [int] NULL,
110
- location_id [int] NULL,
111
- name [varchar](50) NOT NULL
112
- );
113
-
114
- CREATE TABLE comments (
115
- id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL,
116
- article_id [int] NOT NULL,
117
- person_id [int] NOT NULL,
118
- person_type varchar(100) NULL
119
- );
120
-
121
- CREATE TABLE restaurants (
122
- franchise_id [int] NOT NULL,
123
- store_id [int] NOT NULL,
124
- name [varchar](100),
125
- lock_version [int] DEFAULT 0
126
- CONSTRAINT [restaurants_pk] PRIMARY KEY CLUSTERED
127
- ( [franchise_id], [store_id] )
128
- );
129
-
130
- CREATE TABLE restaurants_suburbs (
131
- franchise_id [int] NOT NULL,
132
- store_id [int] NOT NULL,
133
- city_id [int] NOT NULL,
134
- suburb_id [int] NOT NULL
135
- );
136
-
137
- CREATE TABLE dorms (
138
- id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL
139
- );
140
-
141
- CREATE TABLE rooms (
142
- dorm_id [int] NOT NULL,
143
- room_id [int] NOT NULL,
144
- CONSTRAINT [rooms_pk] PRIMARY KEY CLUSTERED
145
- ( [dorm_id], [room_id] )
146
- );
147
-
148
- CREATE TABLE room_attributes (
149
- id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL,
150
- name [varchar](50)
151
- );
152
-
153
- CREATE TABLE room_attribute_assignments (
154
- dorm_id [int] NOT NULL,
155
- room_id [int] NOT NULL,
156
- room_attribute_id [int] NOT NULL
157
- );
158
-
159
- CREATE TABLE staff_rooms (
160
- dorm_id [int] NOT NULL,
161
- room_id [int] NOT NULL,
162
- CONSTRAINT [staff_rooms_pk] PRIMARY KEY CLUSTERED
163
- ( [dorm_id], [room_id] )
164
- );
165
-
166
- CREATE TABLE staff_room_keys (
167
- dorm_id [int] NOT NULL,
168
- room_id [int] NOT NULL,
169
- key_no [varchar](50) NOT NULL,
170
- CONSTRAINT [staff_room_keys_pk] PRIMARY KEY CLUSTERED
171
- ( [dorm_id], [room_id] )
172
- );
173
-
174
- CREATE TABLE students (
175
- id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL
176
- );
177
-
178
- CREATE TABLE room_assignments (
179
- student_id [int] NOT NULL,
180
- dorm_id [int] NOT NULL,
181
- room_id [int] NOT NULL
182
- );
183
-
184
- CREATE TABLE capitols (
185
- country varchar(450) NOT NULL,
186
- city varchar(450) NOT NULL
187
- CONSTRAINT [capitols_pk] PRIMARY KEY
188
- ( [country], [city] )
189
- );
190
-
191
- CREATE TABLE products_restaurants (
192
- product_id [int] NOT NULL,
193
- franchise_id [int] NOT NULL,
194
- store_id [int] NOT NULL
195
- );
196
-
197
- CREATE TABLE employees_groups (
198
- employee_id [int] not null,
199
- group_id [int] not null
1
+ USE [composite_primary_keys_unittest];
2
+
3
+ CREATE TABLE reference_types (
4
+ reference_type_id [int] IDENTITY(1000,1) NOT NULL,
5
+ type_label [varchar](50) NULL,
6
+ abbreviation [varchar](50) NULL,
7
+ description [varchar](50) NULL
8
+ );
9
+
10
+ CREATE TABLE reference_codes (
11
+ reference_type_id [int],
12
+ reference_code [int],
13
+ code_label [varchar](50) NULL,
14
+ abbreviation [varchar](50) NULL,
15
+ description [varchar](50) NULL
16
+ );
17
+
18
+ CREATE TABLE products (
19
+ id [int] IDENTITY(1000,1) NOT NULL,
20
+ name [varchar](50) NULL
21
+ );
22
+
23
+ CREATE TABLE tariffs (
24
+ [tariff_id] [int],
25
+ [start_date] [date],
26
+ [amount] [int] NULL,
27
+ [created_at] [datetimeoffset](7) NOT NULL,
28
+ [updated_at] [datetimeoffset](7) NOT NULL
29
+ CONSTRAINT [tariffs_pk] PRIMARY KEY
30
+ ( [tariff_id], [start_date] )
31
+ );
32
+
33
+ CREATE TABLE product_tariffs (
34
+ [product_id] [int],
35
+ [tariff_id] [int],
36
+ [tariff_start_date] [date]
37
+ CONSTRAINT [product_tariffs_pk] PRIMARY KEY
38
+ ( [product_id], [tariff_id], [tariff_start_date] )
39
+ );
40
+
41
+ CREATE TABLE suburbs (
42
+ city_id [int],
43
+ suburb_id [int],
44
+ name varchar(50) not null,
45
+ CONSTRAINT [suburbs_pk] PRIMARY KEY
46
+ ( [city_id], [suburb_id] )
47
+ );
48
+
49
+ CREATE TABLE streets (
50
+ id [int] IDENTITY(1000,1) NOT NULL,
51
+ city_id [int] NOT NULL,
52
+ suburb_id [int] NOT NULL,
53
+ name [varchar](50) NOT NULL
54
+ );
55
+
56
+ CREATE TABLE users (
57
+ id [int] IDENTITY(1000,1) NOT NULL,
58
+ name varchar(50) NOT NULL
59
+ );
60
+
61
+ CREATE TABLE moderators (
62
+ id [int] PRIMARY KEY
63
+ );
64
+
65
+ CREATE TABLE admins (
66
+ id [int] PRIMARY KEY
67
+ );
68
+
69
+ CREATE TABLE articles (
70
+ id [int] IDENTITY(1000,1) NOT NULL,
71
+ name varchar(50) NOT NULL
72
+ );
73
+
74
+ CREATE TABLE readings (
75
+ id [int] PRIMARY KEY,
76
+ user_id [int] NOT NULL,
77
+ article_id [int] NOT NULL,
78
+ rating [int] NOT NULL
79
+ );
80
+
81
+ CREATE TABLE groups (
82
+ id [int] IDENTITY(1000,1) NOT NULL,
83
+ name [varchar](50) NOT NULL
84
+ );
85
+
86
+ CREATE TABLE memberships (
87
+ user_id [int] NOT NULL,
88
+ group_id [int] NOT NULL
89
+ CONSTRAINT [memberships_pk] PRIMARY KEY
90
+ ( [user_id], [group_id] )
91
+ );
92
+
93
+ CREATE TABLE membership_statuses (
94
+ id [int] IDENTITY(1,1) NOT NULL,
95
+ user_id [int] not null,
96
+ group_id [int] not null,
97
+ status varchar(50) not null
98
+ );
99
+
100
+ CREATE TABLE departments (
101
+ id [int] IDENTITY(100,1) NOT NULL,
102
+ location_id [int] NOT NULL
103
+ CONSTRAINT [departments_pk] PRIMARY KEY
104
+ ( [id], [location_id] )
105
+ );
106
+
107
+ CREATE TABLE employees (
108
+ id [int] IDENTITY(1000,1) NOT NULL,
109
+ department_id [int] NULL,
110
+ location_id [int] NULL,
111
+ name [varchar](50) NOT NULL
112
+ );
113
+
114
+ CREATE TABLE comments (
115
+ id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL,
116
+ article_id [int] NOT NULL,
117
+ person_id [int] NOT NULL,
118
+ person_type varchar(100) NULL
119
+ );
120
+
121
+ CREATE TABLE restaurants (
122
+ franchise_id [int] NOT NULL,
123
+ store_id [int] NOT NULL,
124
+ name [varchar](100),
125
+ lock_version [int] DEFAULT 0
126
+ CONSTRAINT [restaurants_pk] PRIMARY KEY CLUSTERED
127
+ ( [franchise_id], [store_id] )
128
+ );
129
+
130
+ CREATE TABLE restaurants_suburbs (
131
+ franchise_id [int] NOT NULL,
132
+ store_id [int] NOT NULL,
133
+ city_id [int] NOT NULL,
134
+ suburb_id [int] NOT NULL
135
+ );
136
+
137
+ CREATE TABLE dorms (
138
+ id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL
139
+ );
140
+
141
+ CREATE TABLE rooms (
142
+ dorm_id [int] NOT NULL,
143
+ room_id [int] NOT NULL,
144
+ CONSTRAINT [rooms_pk] PRIMARY KEY CLUSTERED
145
+ ( [dorm_id], [room_id] )
146
+ );
147
+
148
+ CREATE TABLE room_attributes (
149
+ id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL,
150
+ name [varchar](50)
151
+ );
152
+
153
+ CREATE TABLE room_attribute_assignments (
154
+ dorm_id [int] NOT NULL,
155
+ room_id [int] NOT NULL,
156
+ room_attribute_id [int] NOT NULL
157
+ );
158
+
159
+ CREATE TABLE staff_rooms (
160
+ dorm_id [int] NOT NULL,
161
+ room_id [int] NOT NULL,
162
+ CONSTRAINT [staff_rooms_pk] PRIMARY KEY CLUSTERED
163
+ ( [dorm_id], [room_id] )
164
+ );
165
+
166
+ CREATE TABLE staff_room_keys (
167
+ dorm_id [int] NOT NULL,
168
+ room_id [int] NOT NULL,
169
+ key_no [varchar](50) NOT NULL,
170
+ CONSTRAINT [staff_room_keys_pk] PRIMARY KEY CLUSTERED
171
+ ( [dorm_id], [room_id] )
172
+ );
173
+
174
+ CREATE TABLE students (
175
+ id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL
176
+ );
177
+
178
+ CREATE TABLE room_assignments (
179
+ student_id [int] NOT NULL,
180
+ dorm_id [int] NOT NULL,
181
+ room_id [int] NOT NULL
182
+ );
183
+
184
+ CREATE TABLE capitols (
185
+ country varchar(450) NOT NULL,
186
+ city varchar(450) NOT NULL
187
+ CONSTRAINT [capitols_pk] PRIMARY KEY
188
+ ( [country], [city] )
189
+ );
190
+
191
+ CREATE TABLE products_restaurants (
192
+ product_id [int] NOT NULL,
193
+ franchise_id [int] NOT NULL,
194
+ store_id [int] NOT NULL
195
+ );
196
+
197
+ CREATE TABLE employees_groups (
198
+ employee_id [int] not null,
199
+ group_id [int] not null
200
200
  );
@@ -1,20 +1,20 @@
1
- class Department < ActiveRecord::Base
2
- self.primary_keys = :id, :location_id
3
-
4
- has_many :employees,
5
- # We intentionally redefine primary key for test purposes. #455
6
- :primary_key => [:id, :location_id],
7
- :foreign_key => [:department_id, :location_id]
8
-
9
- has_many :comments, :through => :employees
10
-
11
- has_one :head, :class_name => 'Employee', :autosave => true, :dependent => :delete,
12
- # We intentionally redefine primary key for test purposes. #455
13
- :primary_key => [:id, :location_id],
14
- :foreign_key => [:department_id, :location_id]
15
-
16
- has_one :head_without_autosave, :class_name => 'Employee',
17
- # We intentionally redefine primary key for test purposes. #455
18
- :primary_key => [:id, :location_id],
19
- :foreign_key => [:department_id, :location_id]
20
- end
1
+ class Department < ActiveRecord::Base
2
+ self.primary_keys = :id, :location_id
3
+
4
+ has_many :employees,
5
+ # We intentionally redefine primary key for test purposes. #455
6
+ :primary_key => [:id, :location_id],
7
+ :foreign_key => [:department_id, :location_id]
8
+
9
+ has_many :comments, :through => :employees
10
+
11
+ has_one :head, :class_name => 'Employee', :autosave => true, :dependent => :delete,
12
+ # We intentionally redefine primary key for test purposes. #455
13
+ :primary_key => [:id, :location_id],
14
+ :foreign_key => [:department_id, :location_id]
15
+
16
+ has_one :head_without_autosave, :class_name => 'Employee',
17
+ # We intentionally redefine primary key for test purposes. #455
18
+ :primary_key => [:id, :location_id],
19
+ :foreign_key => [:department_id, :location_id]
20
+ end
@@ -1,4 +1,4 @@
1
- class Moderator < ActiveRecord::Base
2
- belongs_to :user, :foreign_key => :id, :inverse_of => :moderator
3
- has_one :admin, :foreign_key => :id, :inverse_of => :moderator
4
- end
1
+ class Moderator < ActiveRecord::Base
2
+ belongs_to :user, :foreign_key => :id, :inverse_of => :moderator
3
+ has_one :admin, :foreign_key => :id, :inverse_of => :moderator
4
+ end
@@ -1,14 +1,14 @@
1
- class Room < ActiveRecord::Base
2
- self.primary_keys = :dorm_id, :room_id
3
- belongs_to :dorm
4
- has_many :room_assignments, :foreign_key => [:dorm_id, :room_id]
5
- has_many :room_attribute_assignments, :foreign_key => [:dorm_id, :room_id]
6
- has_many :room_attributes, :through => :room_attribute_assignments
7
-
8
- has_one :staff_room, :foreign_key => [:dorm_id, :room_id], :inverse_of => :room
9
- delegate :staff_room_key, :to => :staff_room, :allow_nil => true
10
-
11
- def find_custom_room_attributes
12
- room_attributes.where("room_attributes.name != ?", "type")
13
- end
14
- end
1
+ class Room < ActiveRecord::Base
2
+ self.primary_keys = :dorm_id, :room_id
3
+ belongs_to :dorm
4
+ has_many :room_assignments, :foreign_key => [:dorm_id, :room_id]
5
+ has_many :room_attribute_assignments, :foreign_key => [:dorm_id, :room_id]
6
+ has_many :room_attributes, :through => :room_attribute_assignments
7
+
8
+ has_one :staff_room, :foreign_key => [:dorm_id, :room_id], :inverse_of => :room
9
+ delegate :staff_room_key, :to => :staff_room, :allow_nil => true
10
+
11
+ def find_custom_room_attributes
12
+ room_attributes.where("room_attributes.name != ?", "type")
13
+ end
14
+ end
@@ -1,18 +1,18 @@
1
- class RoomAssignment < ActiveRecord::Base
2
- self.primary_keys = :student_id, :dorm_id, :room_id
3
- belongs_to :student
4
- belongs_to :room, :foreign_key => [:dorm_id, :room_id], :primary_key => [:dorm_id, :room_id]
5
- validates :student_id, uniqueness: {
6
- conditions: ->(record) {
7
- where(student_id: record.student_id) # enough just to exercise this code path
8
- }
9
- }
10
-
11
- before_destroy do |record|
12
- puts record
13
- end
14
-
15
- after_destroy do |record|
16
- puts record
17
- end
18
- end
1
+ class RoomAssignment < ActiveRecord::Base
2
+ self.primary_keys = :student_id, :dorm_id, :room_id
3
+ belongs_to :student
4
+ belongs_to :room, :foreign_key => [:dorm_id, :room_id], :primary_key => [:dorm_id, :room_id]
5
+ validates :student_id, uniqueness: {
6
+ conditions: ->(record) {
7
+ where(student_id: record.student_id) # enough just to exercise this code path
8
+ }
9
+ }
10
+
11
+ before_destroy do |record|
12
+ puts record
13
+ end
14
+
15
+ after_destroy do |record|
16
+ puts record
17
+ end
18
+ end
@@ -1,6 +1,6 @@
1
- class StaffRoom < ActiveRecord::Base
2
- self.primary_keys = :dorm_id, :room_id
3
-
4
- belongs_to :room, :foreign_key => [:dorm_id, :room_id], :inverse_of => :staff_room
5
- has_one :staff_room_key, :foreign_key => [:dorm_id, :room_id], :inverse_of => :staff_room
6
- end
1
+ class StaffRoom < ActiveRecord::Base
2
+ self.primary_keys = :dorm_id, :room_id
3
+
4
+ belongs_to :room, :foreign_key => [:dorm_id, :room_id], :inverse_of => :staff_room
5
+ has_one :staff_room_key, :foreign_key => [:dorm_id, :room_id], :inverse_of => :staff_room
6
+ end
@@ -1,6 +1,6 @@
1
- class StaffRoomKey < ActiveRecord::Base
2
- self.primary_keys = :dorm_id, :room_id
3
-
4
- belongs_to :staff_room, :foreign_key => [:dorm_id, :room_id], :inverse_of => :staff_room_key
5
- has_one :room, :through => :staff_room
6
- end
1
+ class StaffRoomKey < ActiveRecord::Base
2
+ self.primary_keys = :dorm_id, :room_id
3
+
4
+ belongs_to :staff_room, :foreign_key => [:dorm_id, :room_id], :inverse_of => :staff_room_key
5
+ has_one :room, :through => :staff_room
6
+ end
@@ -1,14 +1,14 @@
1
- class User < ActiveRecord::Base
2
- has_many :readings
3
- has_many :articles, :through => :readings
4
-
5
- has_many :comments, :as => :person
6
- has_one :first_comment, :as => :person, :class_name => "Comment"
7
-
8
- has_one :moderator, :foreign_key => :id, :inverse_of => :user
9
- delegate :admin, :to => :moderator, :allow_nil => true
10
-
11
- def find_custom_articles
12
- articles.where("name = ?", "Article One")
13
- end
14
- end
1
+ class User < ActiveRecord::Base
2
+ has_many :readings
3
+ has_many :articles, :through => :readings
4
+
5
+ has_many :comments, :as => :person
6
+ has_one :first_comment, :as => :person, :class_name => "Comment"
7
+
8
+ has_one :moderator, :foreign_key => :id, :inverse_of => :user
9
+ delegate :admin, :to => :moderator, :allow_nil => true
10
+
11
+ def find_custom_articles
12
+ articles.where("name = ?", "Article One")
13
+ end
14
+ end