rabbit-slide-yancya-evacuate_from_sti 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0b0692b790bd3a14da6769f938b8d0c45812730c
4
+ data.tar.gz: 5ab1e08304cfa811e5674029f551da72d4faf02a
5
+ SHA512:
6
+ metadata.gz: df4f94ca33ad865c0f26a72c2452c953cf6e4f5e842ff822b7a85a97ff7f9c68dfe751ee95516b33f4b5eccac841868025d5ca5ddc4cfdc57ac5957d1f0d6c34
7
+ data.tar.gz: e93b882f9fed7e9b30585d6c6e8e38346ba7641a9d8bce2d733e24c30ce7a9074197fc315920e617ab9231be48e0f374e66d1e0f695be52629e7c4afcd4db23d
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ evacuate_from_sti.rab
data/README.rd ADDED
@@ -0,0 +1,25 @@
1
+ = Evacuate from STI
2
+
3
+ RubyHiroba 2014 の生活発表会で発表したスライドです
4
+ STI についてと、それを避けたらどういう実装がありうるかという話です
5
+
6
+ == 作者向け
7
+
8
+ === 表示
9
+
10
+ rake
11
+
12
+ === 公開
13
+
14
+ rake publish
15
+
16
+ == 閲覧者向け
17
+
18
+ === インストール
19
+
20
+ gem install rabbit-slide-yancya-evacuate_from_sti
21
+
22
+ === 表示
23
+
24
+ rabbit rabbit-slide-yancya-evacuate_from_sti.gem
25
+
data/README.rd~ ADDED
@@ -0,0 +1,24 @@
1
+ = TODO: スライドのタイトル
2
+
3
+ TODO: スライドの説明
4
+
5
+ == 作者向け
6
+
7
+ === 表示
8
+
9
+ rake
10
+
11
+ === 公開
12
+
13
+ rake publish
14
+
15
+ == 閲覧者向け
16
+
17
+ === インストール
18
+
19
+ gem install rabbit-slide-yancya-evacuate_from_sti
20
+
21
+ === 表示
22
+
23
+ rabbit rabbit-slide-yancya-evacuate_from_sti.gem
24
+
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ spec = nil
6
+ Rabbit::Task::Slide.new do |task|
7
+ spec = task.spec
8
+ # task.spec.files += Dir.glob("doc/**/*.*")
9
+ # task.spec.files -= Dir.glob("private/**/*.*")
10
+ # task.spec.add_runtime_dependency("YOUR THEME")
11
+ end
12
+
13
+ desc "Tag #{spec.version}"
14
+ task :tag do
15
+ sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
16
+ sh("git", "push", "--tags")
17
+ end
data/config.yaml ADDED
@@ -0,0 +1,19 @@
1
+ ---
2
+ id: evacuate_from_sti
3
+ base_name: evacuate_from_sti
4
+ tags: []
5
+ presentation_date:
6
+ version: 1.0.0
7
+ licenses: []
8
+ slideshare_id: yancyajp
9
+ speaker_deck_id: yancya
10
+ ustream_id:
11
+ vimeo_id:
12
+ youtube_id:
13
+ author:
14
+ markup_language: :rd
15
+ name: yancya
16
+ email: yancya@upec.jp
17
+ rubygems_user: yancya
18
+ slideshare_user: yancyajp
19
+ speaker_deck_user: yancya
@@ -0,0 +1,321 @@
1
+ = STI を避けたい
2
+
3
+ : subtitle
4
+ I wish I evacuate STI
5
+ : author
6
+ yancya
7
+ # : institution
8
+ # 所属
9
+ : content-source
10
+ RubyHiroba 2014
11
+ : date
12
+ 2014/09/21
13
+ : allotted-time
14
+ 18m
15
+ : theme
16
+ rabbit
17
+
18
+ = 自己紹介
19
+
20
+ # image
21
+ # src = yancya.jpg
22
+ # width = 150
23
+ # height = 150
24
+
25
+ * @yancya
26
+ * 何者でも無い1人の Rubyist
27
+ * 3児の父
28
+
29
+ = STI って使ってます?
30
+
31
+ * どうですか?
32
+
33
+ = STI とは
34
+
35
+ * Single Table Inheritance
36
+ * 単一テーブル継承
37
+ * モデルクラスを継承で表現し、永続化部分はスーパークラスのテーブル1枚でまかなう
38
+
39
+ = STI の実装例(親クラス)
40
+
41
+ # coderay ruby
42
+ class CreateCars < ActiveRecord::Migration
43
+ def change
44
+ create_table :cars do |t|
45
+ t.integer :weight
46
+ t.string :color
47
+ t.string :type
48
+ t.timestamps
49
+ end
50
+ end
51
+ end
52
+
53
+ class Car < ActiveRecord::Base
54
+ end
55
+
56
+ = STI の実装例(親クラス)
57
+
58
+ # coderay ruby
59
+ class CreateCars < ActiveRecord::Migration
60
+ def change
61
+ create_table :cars do |t|
62
+ t.integer :weight
63
+ t.string :color
64
+ t.string :type
65
+ t.timestamps
66
+ end
67
+ end
68
+ end
69
+
70
+ class Car < ActiveRecord::Base
71
+ end
72
+
73
+ = STI の実装例(子クラス)
74
+
75
+ # coderay ruby
76
+ class CreateManualCars < ActiveRecord::Migration
77
+ def change
78
+ # スーパークラスのテーブルにカラムを追加するだけ
79
+ add_column :cars, :number_of_gears, :integer
80
+ end
81
+ end
82
+
83
+ class ManualCar < Car
84
+ end
85
+
86
+ class AutomaticCar < Car
87
+ end
88
+
89
+ = STI の便利さ
90
+
91
+ * サブクラス特有のカラムを add_column して、スーパークラスを継承するだけで作れちゃう便利
92
+ * スーパークラスに共通処理や属性を持たせることで、サブクラスのコードがスッキリ!
93
+
94
+ = STI すごい
95
+
96
+ * メタデータカラムがあるので、親クラスのインスタンスから、子クラスを特定出来たりする
97
+
98
+ # coderay ruby
99
+ AutomaticCar.create(
100
+ weight: 1000,
101
+ color: "blue"
102
+ ) #=> #<AutomaticCar id: 1>
103
+
104
+ Car.find(1).tap{|car|
105
+ break car.type.classify.constantize.find(car.id)
106
+ }.class #=> AutomaticCar
107
+
108
+ = STI の注意点
109
+
110
+ # coderay ruby
111
+ # スーパークラスからサブクラスの属性に触れちゃう
112
+ Car.find(1).number_of_gears #=> 6
113
+ Car.find(1).update(number_of_gears: 5)
114
+
115
+ # それを防ぐために、守るコードを追加
116
+ # gem 'protected_attributes'
117
+ class Car < ActiveRecord::Base
118
+ attr_accessible :weight, :color
119
+ end
120
+
121
+ class ManualCar < Car
122
+ attr_accessible :number_of_gears
123
+ end
124
+
125
+ = 外部キー制約
126
+
127
+ * ついに Rails 本体に外部キー制約サポートがくるよー
128
+
129
+ # blockquote
130
+ # title = http://weblog.rubyonrails.org/2014/8/20/Rails-4-2-beta1/
131
+ Support for real foreign keys!
132
+ add_foreign_key/remove_foreign_key are now available in migrations.
133
+
134
+ = 外部キー制約って使います?
135
+
136
+ * みなさん、どうですか?
137
+
138
+ = STI と外部キー制約
139
+
140
+ * 外部キー制約を使うとして
141
+ * 子クラス特有の属性を定義
142
+ * その属性が外部キー
143
+ * その属性に NOT NULL 制約を付けたいとする
144
+
145
+ = STI で外部キー制約
146
+
147
+ * 親や他の子クラスから INSERT したら NULL が入っちゃう(入らなくてエラー)
148
+ * いいこと思いついた!外部テーブル側に {id: 99999, value: "無し"} みたいなレコードを入れておいて、外部キーに NULL が入りそうになったら、代わりに 99999 を
149
+
150
+ = 例えば、STI を避ける
151
+
152
+ * STI を避ける必要は全然無い
153
+ * 呪われし RDB 厨の業
154
+ * Nullable column
155
+ * 正規化
156
+ * では、しかるべきデータ格納方法とは
157
+
158
+ = STI の背景
159
+
160
+ # blockquote
161
+ # title = http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
162
+ Relational databases don't support inheritance, so when mapping...
163
+
164
+ = RDBMS
165
+
166
+ * みなさん、何使ってます?
167
+
168
+ = PostgreSQL
169
+
170
+ * RDBMS 界の優等生
171
+ * バージョン毎の日本語ドキュメントが充実
172
+ * Heroku のデフォルト RDBMS
173
+ * v9.2 から JSON 型をサポート(v9.3 で更に高機能に)
174
+
175
+ = Table Inherited
176
+
177
+ * "Relational databases don't support inheritance, so when mapping..."
178
+ * テーブルの継承 PostgreSQL にはあるんです
179
+
180
+ = 継承先テーブルの作成
181
+
182
+ # coderay ruby
183
+ class AddManualCar < ActiveRecord::Migration
184
+ def up
185
+ execute <<-SQL
186
+ CREATE TABLE manual_cars(number_of_gears integer)
187
+ INHERITS cars
188
+ SQL
189
+ end
190
+
191
+ def down
192
+ drop_table :manual_cars
193
+ end
194
+ end
195
+
196
+ class AddAutomaticCar < ActiveRecord::Migration
197
+ def up
198
+ execute "CREATE TABLE automatic_cars() INHERITS cars"
199
+ end
200
+
201
+ def down
202
+ drop_table :automatic_cars
203
+ end
204
+ end
205
+
206
+ = Where a row come from?
207
+
208
+ # blockquote
209
+ # title = システム行 - tableoid
210
+ この列は特に、継承階層からの選択問い合わせでは便利です。
211
+ tableoidはテーブル名を得るためにpg_classのoid列に結合することができます。
212
+
213
+ = Behavior of Parental Model
214
+
215
+ # coderay ruby
216
+ module Parental
217
+ def down_cast
218
+ sub_model.find(self)
219
+ end
220
+
221
+ private
222
+ def sub_model
223
+ relation_name = ActiveRecord::Base.connection.execute(<<-SQL).first["relname"]
224
+ SELECT relname
225
+ FROM #{self.class.to_s.tableize} p, pg_class c
226
+ WHERE p.tableoid = c.oid
227
+ AND p.id = #{self.id}
228
+ LIMIT 1
229
+ SQL
230
+
231
+ relation_name.classify.constantize
232
+ end
233
+ end
234
+
235
+ = Behavior of Inherit Model
236
+
237
+ * 継承したままだと table_name がスーパークラスのもの
238
+
239
+ # coderay ruby
240
+ module PgInherits
241
+ extend ActiveSupport::Concern
242
+
243
+ included do |base|
244
+ base.table_name = base.name.tableize
245
+ end
246
+ end
247
+
248
+ = Model Classes
249
+
250
+ # coderay ruby
251
+ class Car < ActiveRecord::Base
252
+ include Parental
253
+ end
254
+
255
+ class ManualCar < Car
256
+ include PgInherits
257
+ end
258
+
259
+ class AutomaticCar < Car
260
+ include PgInherits
261
+ end
262
+
263
+ = テーブル継承の注意点
264
+
265
+ * 多重継承ができる
266
+ * 単にデータベースの機能として見れば便利
267
+ * 多重継承の無いプログラミング言語とマッピングしづらい
268
+
269
+ = テーブル継承の注意点
270
+
271
+ * 親テーブルで PRIMARY KEY, UNIQUE の宣言をしていても、子テーブルまでは制約が伝播しません
272
+ * 親テーブルに外部キーを持って、外部キー制約をつけていても、子テーブルまで制約が伝播しません
273
+
274
+ = テーブル継承の注意点
275
+
276
+ * NOT NULL
277
+ * DEFAULT
278
+ * これらは子テーブルに伝播します
279
+
280
+ = 何が起こりうるか
281
+
282
+ * PRIMARY KEY, UNIQUE について、親まで遡らないので、子テーブルから重複値を入れ放題
283
+ * 子テーブルに別途制約を付けても、子テーブル内でしかチェックしないので根本解決にならない
284
+
285
+ = 具体的に困ること
286
+
287
+ # coderay ruby
288
+ Car.create #=> #<Car id: 1>
289
+ AutomaticCar.create(id: 1) #=> #<AutomaticCar id: 1>
290
+ Car.where(id: 1).count #=> 2
291
+
292
+ ただ、DEFAULT は伝播するので、ID シーケンスは親テーブルと共通なので、ID を直接指定して INSERT UPDATE しなければ問題ない。しなければ
293
+
294
+ = 回避策
295
+
296
+ # coderay ruby
297
+ module PgInherits
298
+ extend ActiveSupport::Concern
299
+
300
+ included do |base|
301
+ base.table_name = base.name.tableize
302
+ # gem 'protected_attributes'
303
+ attr_protected :id
304
+ end
305
+ end
306
+
307
+ = テーブル継承のこれから
308
+
309
+ * PostgreSQL 9.3.2文書 5.8.1 によれば
310
+ * 「これらの機能の不足は、今後のリリースでおそらく改善されるでしょう」とのこと
311
+ * ただ、まぁ Version 7.4 からずっと書いてあるので
312
+
313
+ = まとめ
314
+
315
+ * おとなしく STI を使いましょう
316
+ * でも、必要がなくなったら使うのをやめたい
317
+
318
+ = 質疑応答
319
+
320
+ * もし質問がなければ、こちらから皆さんに質問したり
321
+ * まめ知識を披露しますね
data/yancya.jpg ADDED
Binary file
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-yancya-evacuate_from_sti
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - yancya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rabbit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.2
27
+ description: |-
28
+ RubyHiroba 2014 の生活発表会で発表したスライドです
29
+ STI についてと、それを避けたらどういう実装がありうるかという話です
30
+ email:
31
+ - yancya@upec.jp
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - ".rabbit"
37
+ - README.rd
38
+ - README.rd~
39
+ - Rakefile
40
+ - config.yaml
41
+ - evacuate_from_sti.rab
42
+ - pdf/evacuate_from_sti-evacuate_from_sti.pdf
43
+ - yancya.jpg
44
+ homepage: http://slide.rabbit-shocker.org/authors/yancya/evacuate_from_sti/
45
+ licenses: []
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.2.2
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Evacuate from STI
67
+ test_files: []