/
chapter08code.txt
338 lines (266 loc) · 7.38 KB
/
chapter08code.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
create_table "products" do |t|
t.column "shop_id", :integer
t.column "creator_id", :integer
t.column "name", :string, :default => "Untitled"
t.column "value", :string, :default => "Untitled"
t.column "created_at", :datetime
t.column "updated_at", :datetime
end
create_table :products do |t|
t.integer :shop_id, :creator_id
t.string :name, :value, :default => "Untitled"
t.timestamps
end
require “dbi”
begin
dbiexamp = DBI.connect(“DBI:Mysql:test:localhost”,”root”,”rootpass”) # => connect to DB
added = dbiexamp.do(“insert into account(account_name) values(‘Kevin’)”) # => add a record
puts “added #{added} records” # => added 1 records
dbiexamp.do(“update account set account_name = ‘Kevin Marshall’ where account_name = ‘Kevin’”) # => update record
records = dbiexamp.execute(“select * from account”)
records.fetch do |row|
puts “found account for #{row[“account_name”]}”
end
dbiexamp.do(“delete account where account_name = ‘Kevin Marshall’”) # => delete record
rescue DBI::DatabaseError => error
puts “Error: #{error}”
ensure
dbiexamp.disconnect if dbiexamp
end
require ‘og’
class Account
property :account_name, String
end
Og.setup( { :destroy => false, :store => :mysql, :user => “root”, :password => “rootpass”, :name => “exampledb” }) # => establishes connection and creates any tables that are not yet there.
test = Account.new
test.account_name = “Kevin”
test.save! # => saves the record into the account table
accs = Account.first
puts accs.account_name # => “Kevin”
test.account_name = “Kevin Marshall”
test.save!
puts test.account_username # => Kevin Marshall
test.delete! # => delete the record
database1:
adapter: mysql
host: localhost
username: myuser
password: mypass
database: db1
database2:
adapter: mysql
host: remote.host
username: youruser
password: yourpass
database: db2
require “rubygems”
require “activerecord”
@config = YAML.load_file(File.join(File.dirname(__FILE__), ‘database.yml’))
class LocalDatabase < ActiveRecord::Base
establish_connection @config[‘database1’]
end
class RemoteDatabase < ActiveRecord::Base
establish_connection @config[‘database2’]
end
class Customer < RemoteDatabase
has_many :users
end
class User < LocalDatabase
belongs_to :customer
has_on :email
end
class Email < LocalDatabase
belongs_to :user
end
Module LocalDb
class User < LocalDatabase
belongs_to :customer
has_on :email
end
class Email < LocalDatabase
belongs_to :user
end
end
Module RemoteDb
class User < RemoteDatabase
belongs_to :customer
has_on :email
end
class Email < RemoteDatabase
belongs_to :user
end
end
user = RemoteDb::User.find_by_name(‘Chad Pytel’, :include => [:email], :limit => 1)
new_user = LocalDb::User.new user.attributes
new_user.email = LocalDb::Email.new user.email.attributes
new_user.save
create_table(:accounts, :options => 'DEFAULT CHARSET=utf8') do |t|
t.column :first_name, :string
t.column :last_name, :string
t.column :email, :string
end
gem install uuidtools
require ‘rubygems’
require ‘uuidtools’
module UUIDKeys
def before_create
self.id = UUID.timestamp_create().to_s
end
end
class User < ActiveRecord::Base
include UUIDKeys
# your additional model code
end
class UUIDKeyClass < ActiveRecord::Base
self.abstract_class = true
def before_create
self.id = UUID.timestamp_create().to_s
end
end
class User < UUIDKeyClass
# your additional model code
end
module TableLocking
def lock(options = {})
sql = “LOCK TABLES #{table_name}”
sql += ‘ WRITE’ if options[:write]
sql += ‘ READ’ if options[:read]
execute sql
end
def unlock
execute “UNLOCK TABLES”
end
end
class User < ActiveRecord::Base
include TableLocking
# your additional model code
end
User.lock(:read => true, :write => true)
User.delete(1)
User.unlock
random_record = Model.find(:all)[rand(Model.count)]
random_record = Model.find(rand(Model.count)+1)
random_record = Model.find(:first, :conditions => [“id < ?”, Model.maximum(‘id’)])
class Company < ActiveRecord::Base
has_many :employees
end
class Employee < ActiveRecord::Base
belongs_to :company
end
class Category < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :category
end
class Order < ActiveRecord::Base
has_many :line_items
end
class LineItem < ActiveRecord::Base
belongs_to :product
belongs_to :order
end
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
end
class Roles < ActiveRecord::Base
has_and_belongs_to_many :users
has_and_belongs_to_many :permissions
end
class Permission < ActiveRecord::Base
has_and_belongs_to_many :roles
end
class Survey < ActiveRecord::Base
has_many :questions
has_many :responses
end
class Question < ActiveRecord::Base
belongs_to :survey
has_many :choices
end
class Choice < ActiveRecord::Base
belongs_to :question
end
class Response < ActiveRecord::Base
belongs_to :survey
has_many :response_choices
end
class ResponseChoice < ActiveRecord::Base
belongs_to :response
belongs_to :question
belongs_to :choice
end
class Page < ActiveRecord::Base
acts_as_tree
acts_as_list :scope => :parent
end
class Post < ActiveRecord::Base
has_many :comments, :dependent => true, :order => "created_at ASC"
end
class Comment < ActiveRecord::Base
belongs_to :post
end
class Users < ActiveRecord::Base
has_many :friends, :through => :relationships
has_many :relationships
end
class Relationship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class => User
end
# file: validate_models.rake
# task: rake db:validate_models
namespace :db do
desc "Run model validations on all model records in database"
task :validate_models => :environment do
puts "-- records - model --"
Dir.glob(RAILS_ROOT + '/app/models/**/*.rb').each { |file| require file }
Object.subclasses_of(ActiveRecord::Base).select { |c|
c.base_class == c}.sort_by(&:name).each do |klass|
total = klass.count
printf "%10d - %s\n", total, klass.name
chunk_size = 1000
(total / chunk_size + 1).times do |i|
chunk = klass.find(:all, :offset => (i * chunk_size), :limit => chunk_size)
chunk.reject(&:valid?).each do |record|
puts "#{record.class}: id=#{record.id}"
p record.errors.full_messages
puts
end rescue nil
end
end
end
end
database:
adapter: mysql
host: localhost
username: myuser
password: mypass
database: db1
require "rubygems"
require_gem "activerecord"
config_file = ARGV.shift
environment = ARGV.shift
@config = YAML.load_file(config_file)
ARGV.each { |file| puts file; require file }
Object.subclasses_of(ActiveRecord::Base).select { |c|
c.base_class == c}.sort_by(&:name).each do |klass|
klass.establish_connection @config[environment]
total = klass.count
printf "%10d - %s\n", total, klass.name
chunk_size = 1000
(total / chunk_size + 1).times do |i|
chunk = klass.find(:all, :offset => (i * chunk_size), :limit => chunk_size)
chunk.reject(&:valid?).each do |record|
puts "#{record.class}: id=#{record.id}"
p record.errors.full_messages
puts
end
end rescue nil
end
class Klass < ActiveRecord::Base
def number
attr = attributes_before_type_cast
"#{attr['number']}"
end
end