/
models.rb
213 lines (181 loc) · 5.35 KB
/
models.rb
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
Adapter = Struct.new(:all) do
def find_all(options)
if options[:conditions]
[all.first]
elsif options[:order]
[all.last]
else
all
end
end
end
Association = Struct.new(:klass, :name, :macro, :options)
Column = Struct.new(:name, :type, :limit) do
# Returns +true+ if the column is either of type integer, float or decimal.
def number?
type == :integer || type == :float || type == :decimal
end
end
Company = Struct.new(:id, :name) do
extend ActiveModel::Naming
include ActiveModel::Conversion
def self.all(options={})
(1..3).map { |i| new(i, "#{name} #{i}") }
end
def self.to_adapter
Adapter.new all
end
def persisted?
true
end
end
class Tag < Company; end
TagGroup = Struct.new(:id, :name, :tags)
class User
extend ActiveModel::Naming
include ActiveModel::Conversion
attr_accessor :id, :name, :company, :company_id, :time_zone, :active, :age,
:description, :created_at, :updated_at, :credit_limit, :password, :url,
:delivery_time, :born_at, :special_company_id, :country, :tags, :tag_ids,
:avatar, :home_picture, :email, :status, :residence_country, :phone_number,
:post_count, :lock_version, :amount, :attempts, :action, :credit_card, :gender
def initialize(options={})
@new_record = false
options.each do |key, value|
send("#{key}=", value)
end if options
end
def new_record!
@new_record = true
end
def persisted?
!@new_record
end
def company_attributes=(*)
end
def tags_attributes=(*)
end
def column_for_attribute(attribute)
column_type, limit = case attribute.to_sym
when :name, :status, :password then [:string, 100]
when :description then [:text, 200]
when :age then :integer
when :credit_limit then [:decimal, 15]
when :active then :boolean
when :born_at then :date
when :delivery_time then :time
when :created_at then :datetime
when :updated_at then :timestamp
when :lock_version then :integer
when :home_picture then :string
when :amount then :integer
when :attempts then :integer
when :action then :string
when :credit_card then :string
end
Column.new(attribute, column_type, limit)
end
def self.human_attribute_name(attribute)
case attribute
when 'name'
'Super User Name!'
when 'description'
'User Description!'
when 'company'
'Company Human Name!'
else
attribute.humanize
end
end
def self.reflect_on_association(association)
case association
when :company
Association.new(Company, association, :belongs_to, {})
when :tags
Association.new(Tag, association, :has_many, {})
when :first_company
Association.new(Company, association, :has_one, {})
when :special_company
Association.new(Company, association, :belongs_to, { conditions: { id: 1 } })
end
end
def errors
@errors ||= begin
hash = Hash.new { |h,k| h[k] = [] }
hash.merge!(
name: ["can't be blank"],
description: ["must be longer than 15 characters"],
age: ["is not a number", "must be greater than 18"],
company: ["company must be present"],
company_id: ["must be valid"]
)
end
end
def self.readonly_attributes
["credit_card"]
end
end
class ValidatingUser < User
include ActiveModel::Validations
validates :name, presence: true
validates :company, presence: true
validates :age, presence: true, if: Proc.new { |user| user.name }
validates :amount, presence: true, unless: Proc.new { |user| user.age }
validates :action, presence: true, on: :create
validates :credit_limit, presence: true, on: :save
validates :phone_number, presence: true, on: :update
validates_numericality_of :age,
greater_than_or_equal_to: 18,
less_than_or_equal_to: 99,
only_integer: true
validates_numericality_of :amount,
greater_than: :min_amount,
less_than: :max_amount,
only_integer: true
validates_numericality_of :attempts,
greater_than_or_equal_to: :min_attempts,
less_than_or_equal_to: :max_attempts,
only_integer: true
validates_length_of :name, maximum: 25
validates_length_of :description, maximum: 50
validates_length_of :action, maximum: 10, tokenizer: lambda { |str| str.scan(/\w+/) }
validates_length_of :home_picture, is: 12
def min_amount
10
end
def max_amount
100
end
def min_attempts
1
end
def max_attempts
100
end
end
class OtherValidatingUser < User
include ActiveModel::Validations
validates_numericality_of :age,
greater_than: 17,
less_than: 100,
only_integer: true
validates_numericality_of :amount,
greater_than: Proc.new { |user| user.age },
less_than: Proc.new { |user| user.age + 100 },
only_integer: true
validates_numericality_of :attempts,
greater_than_or_equal_to: Proc.new { |user| user.age },
less_than_or_equal_to: Proc.new { |user| user.age + 100 },
only_integer: true
validates_format_of :country, with: /\w+/
validates_format_of :name, with: Proc.new { /\w+/ }
validates_format_of :description, without: /\d+/
end
class HashBackedAuthor < Hash
extend ActiveModel::Naming
include ActiveModel::Conversion
def persisted?; false; end
def name
'hash backed author'
end
end