detailed 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|