detailed 0.0.5 → 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/COPYING +19 -0
- data/README.md +128 -0
- data/lib/detailed.rb +22 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 08d3b3c0a6e1ab82b95a455566c1e2b6dcb4d9f6
|
4
|
+
data.tar.gz: 37143a1fa1c5c2f3b02fae20311845e39094077f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 907355ad9a27966bac60f4af6cbfe894f40b916fc1226852fb9997b4782a8227e96e95f7045ed8cc65d0b6251066f501aed86b187e92e44964e9724d2cf2f57c
|
7
|
+
data.tar.gz: 26dddeb82242f3a1b3bc791f07e65c2ba4d9f5f8df2c62e9ac42d8b157da9638c637e5efa655483861aba5f4dc7432d595b9f5b5d736f2dda91796d0495067fa
|
data/COPYING
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2014 Marcin Łabanowski
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
detailed
|
2
|
+
========
|
3
|
+
|
4
|
+
Compromise between single and multiple table inheritance with ActiveRecord. This gem doesn't
|
5
|
+
depend on Rails at all (that's, in fact, how it originated).
|
6
|
+
|
7
|
+
With this gem you can have a table hierarchy like this:
|
8
|
+
user (id, type (class), login, password)
|
9
|
+
|- user_client_details (client_id, billing_address, phone_number)
|
10
|
+
|- user_worker_details (worker_id, wage, bank_account)
|
11
|
+
`- user_supplier_details (supplier_id, company_name)
|
12
|
+
|
13
|
+
And models hierarchy like this:
|
14
|
+
ActiveRecord::Base
|
15
|
+
|- User
|
16
|
+
| |- Client
|
17
|
+
| |- Worker
|
18
|
+
| `- Supplier
|
19
|
+
|- UserWorkerDetail
|
20
|
+
|- UserClientDetail
|
21
|
+
`- UserSupplierDetail
|
22
|
+
|
23
|
+
All detail classes would look like this (nothing more is needed):
|
24
|
+
UserWorkerDetail < ActiveRecord::Base
|
25
|
+
belongs_to :worker
|
26
|
+
end
|
27
|
+
|
28
|
+
The main class should be in this form:
|
29
|
+
class User < ActiveRecord::Base
|
30
|
+
# ... your code here ...
|
31
|
+
|
32
|
+
include Detailed
|
33
|
+
end
|
34
|
+
|
35
|
+
The subclasses should be in this form:
|
36
|
+
class Client < User
|
37
|
+
request_details
|
38
|
+
|
39
|
+
# ... your code here ...
|
40
|
+
end
|
41
|
+
|
42
|
+
To add this package to your environment, add the following line to your Gemfile:
|
43
|
+
gem "detailed"
|
44
|
+
|
45
|
+
This gem started from this post on StackExchange: http://stackoverflow.com/a/1634734/3256901 .
|
46
|
+
|
47
|
+
|
48
|
+
Access to detailed properties
|
49
|
+
-----------------------------
|
50
|
+
With the tableset above, we can access our variables directly, like
|
51
|
+
client = new Client
|
52
|
+
client.login = "teh1234" # a field of user
|
53
|
+
client.billing_address = "Zgoda 18/2" # a field of user_client_details
|
54
|
+
client.save
|
55
|
+
|
56
|
+
Be aware, that you can't issue find/where with extended fields at the current
|
57
|
+
time. You need to resort to the regular:
|
58
|
+
Client.find("details_of_client.billing_address" => "Zgoda 18/2")
|
59
|
+
|
60
|
+
|
61
|
+
Subclasses' associations
|
62
|
+
------------------------
|
63
|
+
Your subclasses can have relations directly, without touching the detail models (even
|
64
|
+
though their tables will carry the foreign keys).
|
65
|
+
|
66
|
+
Let's suppose, that your Worker has one avatar...
|
67
|
+
|
68
|
+
class Worker < User
|
69
|
+
...
|
70
|
+
request_details
|
71
|
+
has_one :avarar
|
72
|
+
...
|
73
|
+
end
|
74
|
+
|
75
|
+
On the way back, this is a bit more complicated:
|
76
|
+
|
77
|
+
class Avatar < ActiveRecord::Base
|
78
|
+
...
|
79
|
+
belongs_to :worker, foreign_key: "user_worker_details.avatar_id"
|
80
|
+
...
|
81
|
+
end
|
82
|
+
|
83
|
+
Please be aware, that the "dot notation" of the foreign key is an extension to
|
84
|
+
ActiveRecord provided by this gem.
|
85
|
+
|
86
|
+
NB.: Other sorts of associations than has_one are currently untested.
|
87
|
+
|
88
|
+
|
89
|
+
N+1 query problem
|
90
|
+
-----------------
|
91
|
+
This is an optimization problem. When you want to list all your users, casting
|
92
|
+
them to appropriate models and fetching their details, you can do:
|
93
|
+
|
94
|
+
User.all
|
95
|
+
|
96
|
+
Unfortunately, this method causes you to do N+1 queries (one for all users, and
|
97
|
+
each another one for details). This is because ActiveRecord doesn't know a class
|
98
|
+
of a given record in advance.
|
99
|
+
|
100
|
+
On the other hand, you can instruct ActiveRecord, that all details will be needed
|
101
|
+
by issuing this call:
|
102
|
+
|
103
|
+
User.all_with_details
|
104
|
+
|
105
|
+
ActiveRecord will now run 1+m queries, where m is the number of subclasses, so
|
106
|
+
for our users it will be 4 queries.
|
107
|
+
|
108
|
+
|
109
|
+
Subclasses without details
|
110
|
+
--------------------------
|
111
|
+
Sometimes you are going to subclass the main model without the need for additional
|
112
|
+
fields. This is easy, you just do
|
113
|
+
|
114
|
+
class BasicUser < User
|
115
|
+
end
|
116
|
+
|
117
|
+
No further code needed, detailed won't go into your way.
|
118
|
+
|
119
|
+
|
120
|
+
Subclasses of subclasses
|
121
|
+
------------------------
|
122
|
+
This is currently not tested nor supported, though possible with small changes to
|
123
|
+
this code. Patches are welcome.
|
124
|
+
|
125
|
+
|
126
|
+
License
|
127
|
+
-------
|
128
|
+
This code is licensed under the MIT license. See file COPYING for details.
|
data/lib/detailed.rb
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
# detailed.rb
|
2
|
+
# Copyright (c) 2014 Marcin Łabanowski
|
3
|
+
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
|
1
22
|
require "active_record/associations/association_scope.rb"
|
2
23
|
|
3
24
|
module Detailed
|
@@ -180,4 +201,4 @@ end
|
|
180
201
|
|
181
202
|
class ActiveRecord::Associations::AssociationScope
|
182
203
|
include Detailed::AssociationScope
|
183
|
-
end
|
204
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: detailed
|
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
|
- Marcin Łabanowski
|
@@ -17,6 +17,8 @@ executables: []
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- COPYING
|
21
|
+
- README.md
|
20
22
|
- lib/detailed.rb
|
21
23
|
homepage: http://github.com/czaks/detailed
|
22
24
|
licenses:
|