railties 3.1.0.rc4 → 3.1.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -9
- data/bin/rails +2 -0
- data/guides/assets/images/rails_welcome.png +0 -0
- data/guides/rails_guides/generator.rb +1 -1
- data/guides/rails_guides/textile_extensions.rb +18 -17
- data/guides/source/3_0_release_notes.textile +21 -21
- data/guides/source/action_controller_overview.textile +1 -1
- data/guides/source/action_mailer_basics.textile +27 -6
- data/guides/source/action_view_overview.textile +6 -6
- data/guides/source/active_record_querying.textile +77 -7
- data/guides/source/active_record_validations_callbacks.textile +78 -81
- data/guides/source/active_support_core_extensions.textile +87 -31
- data/guides/source/ajax_on_rails.textile +1 -1
- data/guides/source/api_documentation_guidelines.textile +12 -8
- data/guides/source/asset_pipeline.textile +416 -0
- data/guides/source/association_basics.textile +2 -4
- data/guides/source/caching_with_rails.textile +7 -6
- data/guides/source/command_line.textile +78 -116
- data/guides/source/configuring.textile +34 -17
- data/guides/source/contribute.textile +1 -1
- data/guides/source/contributing_to_ruby_on_rails.textile +3 -3
- data/guides/source/debugging_rails_applications.textile +2 -2
- data/guides/source/form_helpers.textile +40 -51
- data/guides/source/getting_started.textile +641 -197
- data/guides/source/initialization.textile +4 -4
- data/guides/source/layouts_and_rendering.textile +2 -2
- data/guides/source/migrations.textile +114 -32
- data/guides/source/nested_model_forms.textile +6 -6
- data/guides/source/performance_testing.textile +6 -6
- data/guides/source/plugins.textile +23 -22
- data/guides/source/rails_application_templates.textile +8 -14
- data/guides/source/routing.textile +57 -51
- data/guides/source/ruby_on_rails_guides_guidelines.textile +3 -3
- data/guides/source/security.textile +10 -10
- data/guides/source/testing.textile +1 -1
- data/lib/rails.rb +27 -1
- data/lib/rails/all.rb +1 -0
- data/lib/rails/application.rb +4 -10
- data/lib/rails/application/configuration.rb +3 -12
- data/lib/rails/application/railties.rb +1 -1
- data/lib/rails/engine.rb +53 -42
- data/lib/rails/generators.rb +1 -1
- data/lib/rails/generators/app_base.rb +36 -15
- data/lib/rails/generators/generated_attribute.rb +1 -1
- data/lib/rails/generators/js/assets/assets_generator.rb +13 -0
- data/lib/rails/generators/js/assets/templates/javascript.js +2 -0
- data/lib/rails/generators/rails/app/app_generator.rb +3 -1
- data/lib/rails/generators/rails/app/templates/Gemfile +11 -7
- data/lib/rails/generators/rails/app/templates/config/application.rb +7 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +62 -0
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +3 -12
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +3 -3
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +0 -3
- data/lib/rails/generators/rails/assets/assets_generator.rb +2 -9
- data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +12 -10
- data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +5 -2
- data/lib/rails/generators/rails/plugin_new/templates/Gemfile +6 -3
- data/lib/rails/generators/rails/plugin_new/templates/Rakefile +5 -1
- data/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt +14 -0
- data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +5 -3
- data/lib/rails/info.rb +4 -0
- data/lib/rails/paths.rb +5 -5
- data/lib/rails/railtie.rb +4 -4
- data/lib/rails/tasks.rb +0 -1
- data/lib/rails/tasks/documentation.rake +3 -3
- data/lib/rails/tasks/engine.rake +2 -0
- data/lib/rails/tasks/framework.rake +3 -3
- data/lib/rails/tasks/tmp.rake +1 -1
- data/lib/rails/test_unit/testing.rake +2 -2
- data/lib/rails/version.rb +1 -1
- metadata +19 -33
- data/lib/rails/generators/rails/assets/templates/javascript.js.coffee +0 -3
- data/lib/rails/tasks/assets.rake +0 -21
@@ -166,23 +166,23 @@ Each helper accepts an arbitrary number of attribute names, so with a single lin
|
|
166
166
|
|
167
167
|
All of them accept the +:on+ and +:message+ options, which define when the validation should be run and what message should be added to the +errors+ collection if it fails, respectively. The +:on+ option takes one of the values +:save+ (the default), +:create+ or +:update+. There is a default error message for each one of the validation helpers. These messages are used when the +:message+ option isn't specified. Let's take a look at each one of the available helpers.
|
168
168
|
|
169
|
-
h4. +
|
169
|
+
h4. +acceptance+
|
170
170
|
|
171
171
|
Validates that a checkbox on the user interface was checked when a form was submitted. This is typically used when the user needs to agree to your application's terms of service, confirm reading some text, or any similar concept. This validation is very specific to web applications and this 'acceptance' does not need to be recorded anywhere in your database (if you don't have a field for it, the helper will just create a virtual attribute).
|
172
172
|
|
173
173
|
<ruby>
|
174
174
|
class Person < ActiveRecord::Base
|
175
|
-
|
175
|
+
validates :terms_of_service, :acceptance => true
|
176
176
|
end
|
177
177
|
</ruby>
|
178
178
|
|
179
|
-
The default error message for
|
179
|
+
The default error message for this helper is "_must be accepted_".
|
180
180
|
|
181
|
-
|
181
|
+
It can receive an +:accept+ option, which determines the value that will be considered acceptance. It defaults to "1" and can be easily changed.
|
182
182
|
|
183
183
|
<ruby>
|
184
184
|
class Person < ActiveRecord::Base
|
185
|
-
|
185
|
+
validates :terms_of_service, :acceptance => { :accept => 'yes' }
|
186
186
|
end
|
187
187
|
</ruby>
|
188
188
|
|
@@ -203,13 +203,13 @@ CAUTION: Don't use +validates_associated+ on both ends of your associations. The
|
|
203
203
|
|
204
204
|
The default error message for +validates_associated+ is "_is invalid_". Note that each associated object will contain its own +errors+ collection; errors do not bubble up to the calling model.
|
205
205
|
|
206
|
-
h4. +
|
206
|
+
h4. +confirmation+
|
207
207
|
|
208
208
|
You should use this helper when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with "_confirmation" appended.
|
209
209
|
|
210
210
|
<ruby>
|
211
211
|
class Person < ActiveRecord::Base
|
212
|
-
|
212
|
+
validates :email, :confirmation => true
|
213
213
|
end
|
214
214
|
</ruby>
|
215
215
|
|
@@ -220,70 +220,70 @@ In your view template you could use something like
|
|
220
220
|
<%= text_field :person, :email_confirmation %>
|
221
221
|
</erb>
|
222
222
|
|
223
|
-
This check is performed only if +email_confirmation+ is not +nil+. To require confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at +
|
223
|
+
This check is performed only if +email_confirmation+ is not +nil+. To require confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at +presence+ later on this guide):
|
224
224
|
|
225
225
|
<ruby>
|
226
226
|
class Person < ActiveRecord::Base
|
227
|
-
|
228
|
-
|
227
|
+
validates :email, :confirmation => true
|
228
|
+
validates :email_confirmation, :presence => true
|
229
229
|
end
|
230
230
|
</ruby>
|
231
231
|
|
232
|
-
The default error message for
|
232
|
+
The default error message for this helper is "_doesn't match confirmation_".
|
233
233
|
|
234
|
-
h4. +
|
234
|
+
h4. +exclusion+
|
235
235
|
|
236
236
|
This helper validates that the attributes' values are not included in a given set. In fact, this set can be any enumerable object.
|
237
237
|
|
238
238
|
<ruby>
|
239
239
|
class Account < ActiveRecord::Base
|
240
|
-
|
241
|
-
:message => "Subdomain %{value} is reserved."
|
240
|
+
validates :subdomain, :exclusion => { :in => %w(www us ca jp),
|
241
|
+
:message => "Subdomain %{value} is reserved." }
|
242
242
|
end
|
243
243
|
</ruby>
|
244
244
|
|
245
|
-
The +
|
245
|
+
The +exclusion+ helper has an option +:in+ that receives the set of values that will not be accepted for the validated attributes. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. This example uses the +:message+ option to show how you can include the attribute's value.
|
246
246
|
|
247
|
-
The default error message
|
247
|
+
The default error message is "_is reserved_".
|
248
248
|
|
249
|
-
h4. +
|
249
|
+
h4. +format+
|
250
250
|
|
251
251
|
This helper validates the attributes' values by testing whether they match a given regular expression, which is specified using the +:with+ option.
|
252
252
|
|
253
253
|
<ruby>
|
254
254
|
class Product < ActiveRecord::Base
|
255
|
-
|
256
|
-
:message => "Only letters allowed"
|
255
|
+
validates :legacy_code, :format => { :with => /\A[a-zA-Z]+\z/,
|
256
|
+
:message => "Only letters allowed" }
|
257
257
|
end
|
258
258
|
</ruby>
|
259
259
|
|
260
|
-
The default error message
|
260
|
+
The default error message is "_is invalid_".
|
261
261
|
|
262
|
-
h4. +
|
262
|
+
h4. +inclusion+
|
263
263
|
|
264
264
|
This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object.
|
265
265
|
|
266
266
|
<ruby>
|
267
267
|
class Coffee < ActiveRecord::Base
|
268
|
-
|
269
|
-
:message => "%{value} is not a valid size"
|
268
|
+
validates :size, :inclusion => { :in => %w(small medium large),
|
269
|
+
:message => "%{value} is not a valid size" }
|
270
270
|
end
|
271
271
|
</ruby>
|
272
272
|
|
273
|
-
The +
|
273
|
+
The +inclusion+ helper has an option +:in+ that receives the set of values that will be accepted. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. The previous example uses the +:message+ option to show how you can include the attribute's value.
|
274
274
|
|
275
|
-
The default error message for
|
275
|
+
The default error message for this helper is "_is not included in the list_".
|
276
276
|
|
277
|
-
h4. +
|
277
|
+
h4. +length+
|
278
278
|
|
279
279
|
This helper validates the length of the attributes' values. It provides a variety of options, so you can specify length constraints in different ways:
|
280
280
|
|
281
281
|
<ruby>
|
282
282
|
class Person < ActiveRecord::Base
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
283
|
+
validates :name, :length => { :minimum => 2 }
|
284
|
+
validates :bio, :length => { :maximum => 500 }
|
285
|
+
validates :password, :length => { :in => 6..20 }
|
286
|
+
validates :registration_number, :length => { :is => 6 }
|
287
287
|
end
|
288
288
|
</ruby>
|
289
289
|
|
@@ -298,8 +298,8 @@ The default error messages depend on the type of length validation being perform
|
|
298
298
|
|
299
299
|
<ruby>
|
300
300
|
class Person < ActiveRecord::Base
|
301
|
-
|
302
|
-
:too_long => "%{count} characters is the maximum allowed"
|
301
|
+
validates :bio, :length => { :maximum => 1000,
|
302
|
+
:too_long => "%{count} characters is the maximum allowed" }
|
303
303
|
end
|
304
304
|
</ruby>
|
305
305
|
|
@@ -307,20 +307,21 @@ This helper counts characters by default, but you can split the value in a diffe
|
|
307
307
|
|
308
308
|
<ruby>
|
309
309
|
class Essay < ActiveRecord::Base
|
310
|
-
|
310
|
+
validates :content, :length => {
|
311
311
|
:minimum => 300,
|
312
312
|
:maximum => 400,
|
313
313
|
:tokenizer => lambda { |str| str.scan(/\w+/) },
|
314
314
|
:too_short => "must have at least %{count} words",
|
315
315
|
:too_long => "must have at most %{count} words"
|
316
|
+
}
|
316
317
|
end
|
317
318
|
</ruby>
|
318
319
|
|
319
|
-
Note that the default error messages are plural (e.g., "is too short (minimum is %{count} characters)"). For this reason, when +:minimum+ is 1 you should provide a personalized message or use +validates_presence_of+ instead. When +:in+ or +:within+ have a lower limit of 1, you should either provide a personalized message or call +
|
320
|
+
Note that the default error messages are plural (e.g., "is too short (minimum is %{count} characters)"). For this reason, when +:minimum+ is 1 you should provide a personalized message or use +validates_presence_of+ instead. When +:in+ or +:within+ have a lower limit of 1, you should either provide a personalized message or call +presence+ prior to +length+.
|
320
321
|
|
321
|
-
The +
|
322
|
+
The +size+ helper is an alias for +length+.
|
322
323
|
|
323
|
-
h4. +
|
324
|
+
h4. +numericality+
|
324
325
|
|
325
326
|
This helper validates that your attributes have only numeric values. By default, it will match an optional sign followed by an integral or floating point number. To specify that only integral numbers are allowed set +:only_integer+ to true.
|
326
327
|
|
@@ -336,12 +337,12 @@ WARNING. Note that the regular expression above allows a trailing newline charac
|
|
336
337
|
|
337
338
|
<ruby>
|
338
339
|
class Player < ActiveRecord::Base
|
339
|
-
|
340
|
-
|
340
|
+
validates :points, :numericality => true
|
341
|
+
validates :games_played, :numericality => { :only_integer => true }
|
341
342
|
end
|
342
343
|
</ruby>
|
343
344
|
|
344
|
-
Besides +:only_integer+,
|
345
|
+
Besides +:only_integer+, this helper also accepts the following options to add constraints to acceptable values:
|
345
346
|
|
346
347
|
* +:greater_than+ - Specifies the value must be greater than the supplied value. The default error message for this option is "_must be greater than %{count}_".
|
347
348
|
* +:greater_than_or_equal_to+ - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "_must be greater than or equal to %{count}_".
|
@@ -351,9 +352,9 @@ Besides +:only_integer+, the +validates_numericality_of+ helper also accepts the
|
|
351
352
|
* +:odd+ - Specifies the value must be an odd number if set to true. The default error message for this option is "_must be odd_".
|
352
353
|
* +:even+ - Specifies the value must be an even number if set to true. The default error message for this option is "_must be even_".
|
353
354
|
|
354
|
-
The default error message
|
355
|
+
The default error message is "_is not a number_".
|
355
356
|
|
356
|
-
h4. +
|
357
|
+
h4. +presence+
|
357
358
|
|
358
359
|
This helper validates that the specified attributes are not empty. It uses the +blank?+ method to check if the value is either +nil+ or a blank string, that is, a string that is either empty or consists of whitespace.
|
359
360
|
|
@@ -368,21 +369,21 @@ If you want to be sure that an association is present, you'll need to test wheth
|
|
368
369
|
<ruby>
|
369
370
|
class LineItem < ActiveRecord::Base
|
370
371
|
belongs_to :order
|
371
|
-
|
372
|
+
validates :order_id, :presence => true
|
372
373
|
end
|
373
374
|
</ruby>
|
374
375
|
|
375
|
-
Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use
|
376
|
+
Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use <tt>validates :field_name, :inclusion => { :in => [true, false] }</tt>.
|
376
377
|
|
377
|
-
The default error message
|
378
|
+
The default error message is "_can't be empty_".
|
378
379
|
|
379
|
-
h4. +
|
380
|
+
h4. +uniqueness+
|
380
381
|
|
381
382
|
This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create a unique index in your database.
|
382
383
|
|
383
384
|
<ruby>
|
384
385
|
class Account < ActiveRecord::Base
|
385
|
-
|
386
|
+
validates :email, :uniqueness => true
|
386
387
|
end
|
387
388
|
</ruby>
|
388
389
|
|
@@ -392,8 +393,8 @@ There is a +:scope+ option that you can use to specify other attributes that are
|
|
392
393
|
|
393
394
|
<ruby>
|
394
395
|
class Holiday < ActiveRecord::Base
|
395
|
-
|
396
|
-
:message => "should happen once per year"
|
396
|
+
validates :name, :uniqueness => { :scope => :year,
|
397
|
+
:message => "should happen once per year" }
|
397
398
|
end
|
398
399
|
</ruby>
|
399
400
|
|
@@ -401,13 +402,13 @@ There is also a +:case_sensitive+ option that you can use to define whether the
|
|
401
402
|
|
402
403
|
<ruby>
|
403
404
|
class Person < ActiveRecord::Base
|
404
|
-
|
405
|
+
validates :name, :uniqueness => { :case_sensitive => false }
|
405
406
|
end
|
406
407
|
</ruby>
|
407
408
|
|
408
409
|
WARNING. Note that some databases are configured to perform case-insensitive searches anyway.
|
409
410
|
|
410
|
-
The default error message
|
411
|
+
The default error message is "_has already been taken_".
|
411
412
|
|
412
413
|
h4. +validates_with+
|
413
414
|
|
@@ -471,8 +472,8 @@ The +:allow_nil+ option skips the validation when the value being validated is +
|
|
471
472
|
|
472
473
|
<ruby>
|
473
474
|
class Coffee < ActiveRecord::Base
|
474
|
-
|
475
|
-
:message => "%{value} is not a valid size", :allow_nil => true
|
475
|
+
validates :size, :inclusion => { :in => %w(small medium large),
|
476
|
+
:message => "%{value} is not a valid size" }, :allow_nil => true
|
476
477
|
end
|
477
478
|
</ruby>
|
478
479
|
|
@@ -484,10 +485,10 @@ The +:allow_blank+ option is similar to the +:allow_nil+ option. This option wil
|
|
484
485
|
|
485
486
|
<ruby>
|
486
487
|
class Topic < ActiveRecord::Base
|
487
|
-
|
488
|
+
validates :title, :length => { :is => 5 }, :allow_blank => true
|
488
489
|
end
|
489
490
|
|
490
|
-
Topic.create("title" => "").valid?
|
491
|
+
Topic.create("title" => "").valid? # => true
|
491
492
|
Topic.create("title" => nil).valid? # => true
|
492
493
|
</ruby>
|
493
494
|
|
@@ -504,10 +505,10 @@ The +:on+ option lets you specify when the validation should happen. The default
|
|
504
505
|
<ruby>
|
505
506
|
class Person < ActiveRecord::Base
|
506
507
|
# it will be possible to update email with a duplicated value
|
507
|
-
|
508
|
+
validates :email, :uniqueness => true, :on => :create
|
508
509
|
|
509
510
|
# it will be possible to create the record with a non-numerical age
|
510
|
-
|
511
|
+
validates :age, :numericality => true, :on => :update
|
511
512
|
|
512
513
|
# the default (validates on both create and update)
|
513
514
|
validates :name, :presence => true, :on => :save
|
@@ -524,7 +525,7 @@ You can associate the +:if+ and +:unless+ options with a symbol corresponding to
|
|
524
525
|
|
525
526
|
<ruby>
|
526
527
|
class Order < ActiveRecord::Base
|
527
|
-
|
528
|
+
validates :card_number, :presence => true, :if => :paid_with_card?
|
528
529
|
|
529
530
|
def paid_with_card?
|
530
531
|
payment_type == "card"
|
@@ -538,7 +539,7 @@ You can also use a string that will be evaluated using +eval+ and needs to conta
|
|
538
539
|
|
539
540
|
<ruby>
|
540
541
|
class Person < ActiveRecord::Base
|
541
|
-
|
542
|
+
validates :surname, :presence => true, :if => "name.nil?"
|
542
543
|
end
|
543
544
|
</ruby>
|
544
545
|
|
@@ -548,7 +549,7 @@ Finally, it's possible to associate +:if+ and +:unless+ with a +Proc+ object whi
|
|
548
549
|
|
549
550
|
<ruby>
|
550
551
|
class Account < ActiveRecord::Base
|
551
|
-
|
552
|
+
validates :password, :confirmation => true,
|
552
553
|
:unless => Proc.new { |a| a.password.blank? }
|
553
554
|
end
|
554
555
|
</ruby>
|
@@ -560,8 +561,8 @@ Sometimes it is useful to have multiple validations use one condition, it can be
|
|
560
561
|
<ruby>
|
561
562
|
class User < ActiveRecord::Base
|
562
563
|
with_options :if => :is_admin? do |admin|
|
563
|
-
admin.
|
564
|
-
admin.
|
564
|
+
admin.validates :password, :length => { :minimum => 10 }
|
565
|
+
admin.validates :email, :presence => true
|
565
566
|
end
|
566
567
|
end
|
567
568
|
</ruby>
|
@@ -598,7 +599,7 @@ You can even create your own validation helpers and reuse them in several differ
|
|
598
599
|
<ruby>
|
599
600
|
ActiveRecord::Base.class_eval do
|
600
601
|
def self.validates_as_choice(attr_name, n, options={})
|
601
|
-
|
602
|
+
validates attr_name, :inclusion => { {:in => 1..n}.merge(options) }
|
602
603
|
end
|
603
604
|
end
|
604
605
|
</ruby>
|
@@ -623,8 +624,7 @@ Returns an OrderedHash with all errors. Each key is the attribute name and the v
|
|
623
624
|
|
624
625
|
<ruby>
|
625
626
|
class Person < ActiveRecord::Base
|
626
|
-
validates :name, :presence => true
|
627
|
-
validates_length_of :name, :minimum => 3
|
627
|
+
validates :name, :presence => true, :length => { :minimum => 3 }
|
628
628
|
end
|
629
629
|
|
630
630
|
person = Person.new
|
@@ -643,8 +643,7 @@ h4(#working_with_validation_errors-errors-2). +errors[]+
|
|
643
643
|
|
644
644
|
<ruby>
|
645
645
|
class Person < ActiveRecord::Base
|
646
|
-
validates :name, :presence => true
|
647
|
-
validates_length_of :name, :minimum => 3
|
646
|
+
validates :name, :presence => true, :length => { :minimum => 3 }
|
648
647
|
end
|
649
648
|
|
650
649
|
person = Person.new(:name => "John Doe")
|
@@ -719,8 +718,7 @@ The +clear+ method is used when you intentionally want to clear all the messages
|
|
719
718
|
|
720
719
|
<ruby>
|
721
720
|
class Person < ActiveRecord::Base
|
722
|
-
validates :name, :presence => true
|
723
|
-
validates_length_of :name, :minimum => 3
|
721
|
+
validates :name, :presence => true, :length => { :minimum => 3 }
|
724
722
|
end
|
725
723
|
|
726
724
|
person = Person.new
|
@@ -743,9 +741,7 @@ The +size+ method returns the total number of error messages for the object.
|
|
743
741
|
|
744
742
|
<ruby>
|
745
743
|
class Person < ActiveRecord::Base
|
746
|
-
validates :name, :presence => true
|
747
|
-
validates_length_of :name, :minimum => 3
|
748
|
-
validates_presence_of :email
|
744
|
+
validates :name, :presence => true, :length => { :minimum => 3 }
|
749
745
|
end
|
750
746
|
|
751
747
|
person = Person.new
|
@@ -766,13 +762,14 @@ h4. Installing as a plugin
|
|
766
762
|
$ rails plugin install git://github.com/joelmoss/dynamic_form.git
|
767
763
|
</shell>
|
768
764
|
|
769
|
-
h4 Installing as a Gem
|
770
|
-
|
765
|
+
h4. Installing as a Gem
|
766
|
+
|
767
|
+
Add this line in your Gemfile:
|
771
768
|
<ruby>
|
772
769
|
gem "dynamic_form"
|
773
770
|
</ruby>
|
774
771
|
|
775
|
-
Now you will have access to these two methods in your view templates
|
772
|
+
Now you will have access to these two methods in your view templates.
|
776
773
|
|
777
774
|
h4. +error_messages+ and +error_messages_for+
|
778
775
|
|
@@ -780,8 +777,8 @@ When creating a form with the +form_for+ helper, you can use the +error_messages
|
|
780
777
|
|
781
778
|
<ruby>
|
782
779
|
class Product < ActiveRecord::Base
|
783
|
-
|
784
|
-
|
780
|
+
validates :description, :value, :presence => true
|
781
|
+
validates :value, :numericality => true, :allow_nil => true
|
785
782
|
end
|
786
783
|
</ruby>
|
787
784
|
|
@@ -851,7 +848,7 @@ The way form fields with errors are treated is defined by +ActionView::Base.fiel
|
|
851
848
|
* A string with the HTML tag
|
852
849
|
* An instance of +ActionView::Helpers::InstanceTag+.
|
853
850
|
|
854
|
-
Here is a simple example where we change the Rails
|
851
|
+
Here is a simple example where we change the Rails behavior to always display the error messages in front of each of the form fields with errors. The error messages will be enclosed by a +span+ element with a +validation-error+ CSS class. There will be no +div+ element enclosing the +input+ element, so we get rid of that red border around the text field. You can use the +validation-error+ CSS class to style it anyway you want.
|
855
852
|
|
856
853
|
<ruby>
|
857
854
|
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
|
@@ -879,7 +876,7 @@ In order to use the available callbacks, you need to register them. You can do t
|
|
879
876
|
|
880
877
|
<ruby>
|
881
878
|
class User < ActiveRecord::Base
|
882
|
-
|
879
|
+
validates :login, :email, :presence => true
|
883
880
|
|
884
881
|
before_validation :ensure_login_has_a_value
|
885
882
|
|
@@ -896,7 +893,7 @@ The macro-style class methods can also receive a block. Consider using this styl
|
|
896
893
|
|
897
894
|
<ruby>
|
898
895
|
class User < ActiveRecord::Base
|
899
|
-
|
896
|
+
validates :login, :email, :presence => true
|
900
897
|
|
901
898
|
before_create do |user|
|
902
899
|
user.name = user.login.capitalize if user.name.blank?
|
@@ -944,7 +941,7 @@ The +after_initialize+ callback will be called whenever an Active Record object
|
|
944
941
|
|
945
942
|
The +after_find+ callback will be called whenever Active Record loads a record from the database. +after_find+ is called before +after_initialize+ if both are defined.
|
946
943
|
|
947
|
-
The +after_initialize+ and +after_find+ callbacks are a bit different from the others. They have no +before_*+ counterparts, and the only way to register them is by defining them as regular methods. If you try to register +after_initialize+ or +after_find+ using macro-style class methods, they will just be ignored. This
|
944
|
+
The +after_initialize+ and +after_find+ callbacks are a bit different from the others. They have no +before_*+ counterparts, and the only way to register them is by defining them as regular methods. If you try to register +after_initialize+ or +after_find+ using macro-style class methods, they will just be ignored. This behavior is due to performance reasons, since +after_initialize+ and +after_find+ will both be called for each record found in the database, significantly slowing down the queries.
|
948
945
|
|
949
946
|
<ruby>
|
950
947
|
class User < ActiveRecord::Base
|
@@ -1175,7 +1172,7 @@ As usual, settings in +config/environments+ take precedence over those in +confi
|
|
1175
1172
|
|
1176
1173
|
h4. Sharing Observers
|
1177
1174
|
|
1178
|
-
By default, Rails will simply strip "Observer" from an observer's name to find the model it should observe. However, observers can also be used to add
|
1175
|
+
By default, Rails will simply strip "Observer" from an observer's name to find the model it should observe. However, observers can also be used to add behavior to more than one model, and so it's possible to manually specify the models that our observer should observe.
|
1179
1176
|
|
1180
1177
|
<ruby>
|
1181
1178
|
class MailerObserver < ActiveRecord::Observer
|
@@ -436,20 +436,6 @@ end
|
|
436
436
|
|
437
437
|
NOTE: Defined in +active_support/core_ext/kernel/reporting.rb+.
|
438
438
|
|
439
|
-
h4. +require_library_or_gem+
|
440
|
-
|
441
|
-
The convenience method +require_library_or_gem+ tries to load its argument with a regular +require+ first. If it fails loads +rubygems+ and tries again.
|
442
|
-
|
443
|
-
If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. A +LoadError+ is also raised if +rubygems+ is available but the argument is not loadable as a gem.
|
444
|
-
|
445
|
-
For example, that's the way the MySQL adapter loads the MySQL library:
|
446
|
-
|
447
|
-
<ruby>
|
448
|
-
require_library_or_gem('mysql')
|
449
|
-
</ruby>
|
450
|
-
|
451
|
-
NOTE: Defined in +active_support/core_ext/kernel/requires.rb+.
|
452
|
-
|
453
439
|
h4. +in?+
|
454
440
|
|
455
441
|
The predicate +in?+ tests if an object is included in another object. An +ArgumentError+ exception will be raised if the argument passed does not respond to +include?+.
|
@@ -512,7 +498,7 @@ ActionController::TestCase.class_eval do
|
|
512
498
|
end
|
513
499
|
</ruby>
|
514
500
|
|
515
|
-
Rails uses +alias_method_chain+ all over the code base. For example validations are added to +ActiveRecord::Base#save+ by wrapping the method that way in a separate module
|
501
|
+
Rails uses +alias_method_chain+ all over the code base. For example validations are added to +ActiveRecord::Base#save+ by wrapping the method that way in a separate module specialized in validations.
|
516
502
|
|
517
503
|
NOTE: Defined in +active_support/core_ext/module/aliasing.rb+.
|
518
504
|
|
@@ -961,7 +947,7 @@ h4. Class Attributes
|
|
961
947
|
|
962
948
|
h5. +class_attribute+
|
963
949
|
|
964
|
-
The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy
|
950
|
+
The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy.
|
965
951
|
|
966
952
|
<ruby>
|
967
953
|
class A
|
@@ -997,7 +983,7 @@ self.default_params = {
|
|
997
983
|
}.freeze
|
998
984
|
</ruby>
|
999
985
|
|
1000
|
-
They can be also accessed and overridden at the instance level
|
986
|
+
They can be also accessed and overridden at the instance level.
|
1001
987
|
|
1002
988
|
<ruby>
|
1003
989
|
A.x = 1
|
@@ -1010,7 +996,7 @@ a1.x # => 1, comes from A
|
|
1010
996
|
a2.x # => 2, overridden in a2
|
1011
997
|
</ruby>
|
1012
998
|
|
1013
|
-
The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to false
|
999
|
+
The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to +false+.
|
1014
1000
|
|
1015
1001
|
<ruby>
|
1016
1002
|
module ActiveRecord
|
@@ -1023,8 +1009,20 @@ end
|
|
1023
1009
|
|
1024
1010
|
A model may find that option useful as a way to prevent mass-assignment from setting the attribute.
|
1025
1011
|
|
1012
|
+
The generation of the reader instance method can be prevented by setting the option +:instance_reader+ to +false+.
|
1013
|
+
|
1014
|
+
<ruby>
|
1015
|
+
class A
|
1016
|
+
class_attribute :x, :instance_reader => false
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
A.x = 1 # NoMethodError
|
1020
|
+
</ruby>
|
1021
|
+
|
1026
1022
|
For convenience +class_attribute+ also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+.
|
1027
1023
|
|
1024
|
+
When +:instance_reader+ is +false+, the instance predicate returns a +NoMethodError+ just like the reader method.
|
1025
|
+
|
1028
1026
|
NOTE: Defined in +active_support/core_ext/class/attribute.rb+
|
1029
1027
|
|
1030
1028
|
h5. +cattr_reader+, +cattr_writer+, and +cattr_accessor+
|
@@ -1050,18 +1048,24 @@ module ActionView
|
|
1050
1048
|
end
|
1051
1049
|
</ruby>
|
1052
1050
|
|
1053
|
-
we can access +field_error_proc+ in views.
|
1051
|
+
we can access +field_error_proc+ in views.
|
1052
|
+
|
1053
|
+
The generation of the reader instance method can be prevented by setting +:instance_reader+ to +false+ and the generation of the writer instance method can be prevented by setting +:instance_writer+ to +false+. Generation of both methods can be prevented by setting +:instance_accessor+ to +false+. In all cases, the value must be exactly +false+ and not any false value.
|
1054
1054
|
|
1055
1055
|
<ruby>
|
1056
|
-
module
|
1057
|
-
class
|
1058
|
-
# No
|
1059
|
-
cattr_accessor :
|
1056
|
+
module A
|
1057
|
+
class B
|
1058
|
+
# No first_name instance reader is generated.
|
1059
|
+
cattr_accessor :first_name, :instance_reader => false
|
1060
|
+
# No last_name= instance writer is generated.
|
1061
|
+
cattr_accessor :last_name, :instance_writer => false
|
1062
|
+
# No surname instance reader or surname= writer is generated.
|
1063
|
+
cattr_accessor :surname, :instance_accessor => false
|
1060
1064
|
end
|
1061
1065
|
end
|
1062
1066
|
</ruby>
|
1063
1067
|
|
1064
|
-
A model may find
|
1068
|
+
A model may find it useful to set +:instance_accessor+ to +false+ as a way to prevent mass-assignment from setting the attribute.
|
1065
1069
|
|
1066
1070
|
NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
|
1067
1071
|
|
@@ -1160,8 +1164,12 @@ h3. Extensions to +String+
|
|
1160
1164
|
|
1161
1165
|
h4. Output Safety
|
1162
1166
|
|
1167
|
+
h5. Motivation
|
1168
|
+
|
1163
1169
|
Inserting data into HTML templates needs extra care. For example you can't just interpolate +@review.title+ verbatim into an HTML page. On one hand if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;". On the other hand, depending on the application that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the "section about cross-site scripting in the Security guide":security.html#cross-site-scripting-xss for further information about the risks.
|
1164
1170
|
|
1171
|
+
h5. Safe Strings
|
1172
|
+
|
1165
1173
|
Active Support has the concept of <i>(html) safe</i> strings since Rails 3. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
|
1166
1174
|
|
1167
1175
|
Strings are considered to be <i>unsafe</i> by default:
|
@@ -1187,8 +1195,6 @@ s # => "<script>...</script>"
|
|
1187
1195
|
|
1188
1196
|
It is your responsibility to ensure calling +html_safe+ on a particular string is fine.
|
1189
1197
|
|
1190
|
-
NOTE: For performance reasons safe strings are implemented in a way that cannot offer an in-place +html_safe!+ variant.
|
1191
|
-
|
1192
1198
|
If you append onto a safe string, either in-place with +concat+/<tt><<</tt>, or with <tt>+</tt>, the result is a safe string. Unsafe arguments are escaped:
|
1193
1199
|
|
1194
1200
|
<ruby>
|
@@ -1229,6 +1235,22 @@ end
|
|
1229
1235
|
|
1230
1236
|
NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
|
1231
1237
|
|
1238
|
+
h5. Transformation
|
1239
|
+
|
1240
|
+
As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +donwcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
|
1241
|
+
|
1242
|
+
In the case of in-place transformations like +gsub!+ the receiver itself becomes unsafe.
|
1243
|
+
|
1244
|
+
INFO: The safety bit is lost always, no matter whether the transformation actually changed something.
|
1245
|
+
|
1246
|
+
h5. Conversion and Coercion
|
1247
|
+
|
1248
|
+
Calling +to_s+ on a safe string returns a safe string, but coercion with +to_str+ returns an unsafe string.
|
1249
|
+
|
1250
|
+
h5. Copying
|
1251
|
+
|
1252
|
+
Calling +dup+ or +clone+ on safe strings yields safe strings.
|
1253
|
+
|
1232
1254
|
h4. +squish+
|
1233
1255
|
|
1234
1256
|
The method +squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
|
@@ -1474,7 +1496,15 @@ end
|
|
1474
1496
|
|
1475
1497
|
That may be handy to compute method names in a language that follows that convention, for example JavaScript.
|
1476
1498
|
|
1477
|
-
INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>.
|
1499
|
+
INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>. To support cases such as this, Active Support allows you to specify acronyms in +config/initializers/inflections.rb+:
|
1500
|
+
|
1501
|
+
<ruby>
|
1502
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
1503
|
+
inflect.acronym 'SSL'
|
1504
|
+
end
|
1505
|
+
|
1506
|
+
"SSLError".underscore.camelize #=> "SSLError"
|
1507
|
+
</ruby>
|
1478
1508
|
|
1479
1509
|
+camelize+ is aliased to +camelcase+.
|
1480
1510
|
|
@@ -2219,8 +2249,8 @@ The method +Array.wrap+ wraps its argument in an array unless it is already an a
|
|
2219
2249
|
Specifically:
|
2220
2250
|
|
2221
2251
|
* If the argument is +nil+ an empty list is returned.
|
2222
|
-
* Otherwise, if the argument responds to +to_ary+ it is invoked, and
|
2223
|
-
* Otherwise,
|
2252
|
+
* Otherwise, if the argument responds to +to_ary+ it is invoked, and if the value of +to_ary+ is not +nil+, it is returned.
|
2253
|
+
* Otherwise, an array with the argument as its single element is returned.
|
2224
2254
|
|
2225
2255
|
<ruby>
|
2226
2256
|
Array.wrap(nil) # => []
|
@@ -2296,7 +2326,7 @@ NOTE: Defined in +active_support/core_ext/array/grouping.rb+.
|
|
2296
2326
|
|
2297
2327
|
h5. +in_groups(number, fill_with = nil)+
|
2298
2328
|
|
2299
|
-
The method +in_groups+ splits an array into a certain number of groups. The method returns
|
2329
|
+
The method +in_groups+ splits an array into a certain number of groups. The method returns an array with the groups:
|
2300
2330
|
|
2301
2331
|
<ruby>
|
2302
2332
|
%w(1 2 3 4 5 6 7).in_groups(3)
|
@@ -2728,7 +2758,7 @@ Active Support extends the method +Range#step+ so that it can be invoked without
|
|
2728
2758
|
(1..10).step(2) # => [1, 3, 5, 7, 9]
|
2729
2759
|
</ruby>
|
2730
2760
|
|
2731
|
-
As the example shows, in that case the method returns
|
2761
|
+
As the example shows, in that case the method returns an array with the corresponding elements.
|
2732
2762
|
|
2733
2763
|
NOTE: Defined in +active_support/core_ext/range/blockless_step.rb+.
|
2734
2764
|
|
@@ -3330,6 +3360,32 @@ Active Support defines +Time.current+ to be today in the current time zone. That
|
|
3330
3360
|
|
3331
3361
|
When making Time comparisons using methods which honor the user time zone, make sure to use +Time.current+ and not +Time.now+. There are cases where the user time zone might be in the future compared to the system time zone, which +Time.today+ uses by default. This means +Time.now+ may equal +Time.yesterday+.
|
3332
3362
|
|
3363
|
+
h5. +all_day+, +all_week+, +all_month+, +all_quarter+ and +all_year+
|
3364
|
+
|
3365
|
+
The method +all_day+ returns a range representing the whole day of the current time.
|
3366
|
+
|
3367
|
+
<ruby>
|
3368
|
+
now = Time.current
|
3369
|
+
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
|
3370
|
+
now.all_day
|
3371
|
+
# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00
|
3372
|
+
</ruby>
|
3373
|
+
|
3374
|
+
Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the purpose of generating time ranges.
|
3375
|
+
|
3376
|
+
<ruby>
|
3377
|
+
now = Time.current
|
3378
|
+
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
|
3379
|
+
now.all_week
|
3380
|
+
# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00
|
3381
|
+
now.all_month
|
3382
|
+
# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00
|
3383
|
+
now.all_quarter
|
3384
|
+
# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00
|
3385
|
+
now.all_year
|
3386
|
+
# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00
|
3387
|
+
</ruby>
|
3388
|
+
|
3333
3389
|
h4. Time Constructors
|
3334
3390
|
|
3335
3391
|
Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+:
|