railties 3.0.0.beta2 → 3.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -2
- data/guides/{images → assets/images}/belongs_to.png +0 -0
- data/guides/{images → assets/images}/book_icon.gif +0 -0
- data/guides/{images → assets/images}/bullet.gif +0 -0
- data/guides/{images → assets/images}/challenge.png +0 -0
- data/guides/{images → assets/images}/chapters_icon.gif +0 -0
- data/guides/{images → assets/images}/check_bullet.gif +0 -0
- data/guides/{images → assets/images}/credits_pic_blank.gif +0 -0
- data/guides/{images → assets/images}/csrf.png +0 -0
- data/guides/{images → assets/images}/customized_error_messages.png +0 -0
- data/guides/{images → assets/images}/edge_badge.png +0 -0
- data/guides/{images → assets/images}/error_messages.png +0 -0
- data/guides/{images → assets/images}/feature_tile.gif +0 -0
- data/guides/{images → assets/images}/footer_tile.gif +0 -0
- data/guides/{images → assets/images}/fxn.png +0 -0
- data/guides/{images → assets/images}/grey_bullet.gif +0 -0
- data/guides/{images → assets/images}/habtm.png +0 -0
- data/guides/{images → assets/images}/has_many.png +0 -0
- data/guides/{images → assets/images}/has_many_through.png +0 -0
- data/guides/{images → assets/images}/has_one.png +0 -0
- data/guides/{images → assets/images}/has_one_through.png +0 -0
- data/guides/{images → assets/images}/header_backdrop.png +0 -0
- data/guides/{images → assets/images}/header_tile.gif +0 -0
- data/guides/{images → assets/images}/i18n/demo_localized_pirate.png +0 -0
- data/guides/{images → assets/images}/i18n/demo_translated_en.png +0 -0
- data/guides/{images → assets/images}/i18n/demo_translated_pirate.png +0 -0
- data/guides/{images → assets/images}/i18n/demo_translation_missing.png +0 -0
- data/guides/{images → assets/images}/i18n/demo_untranslated.png +0 -0
- data/guides/{images → assets/images}/icons/README +0 -0
- data/guides/{images → assets/images}/icons/callouts/1.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/10.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/11.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/12.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/13.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/14.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/15.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/2.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/3.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/4.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/5.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/6.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/7.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/8.png +0 -0
- data/guides/{images → assets/images}/icons/callouts/9.png +0 -0
- data/guides/{images → assets/images}/icons/caution.png +0 -0
- data/guides/{images → assets/images}/icons/example.png +0 -0
- data/guides/{images → assets/images}/icons/home.png +0 -0
- data/guides/{images → assets/images}/icons/important.png +0 -0
- data/guides/{images → assets/images}/icons/next.png +0 -0
- data/guides/{images → assets/images}/icons/note.png +0 -0
- data/guides/{images → assets/images}/icons/prev.png +0 -0
- data/guides/{images → assets/images}/icons/tip.png +0 -0
- data/guides/{images → assets/images}/icons/up.png +0 -0
- data/guides/{images → assets/images}/icons/warning.png +0 -0
- data/guides/assets/images/jaimeiniesta.jpg +0 -0
- data/guides/{images → assets/images}/nav_arrow.gif +0 -0
- data/guides/{images → assets/images}/polymorphic.png +0 -0
- data/guides/{images → assets/images}/posts_index.png +0 -0
- data/guides/{images → assets/images}/rails_guides_logo.gif +0 -0
- data/guides/{images → assets/images}/rails_logo_remix.gif +0 -0
- data/guides/{images → assets/images}/rails_welcome.png +0 -0
- data/guides/{images → assets/images}/session_fixation.png +0 -0
- data/guides/{images → assets/images}/tab_grey.gif +0 -0
- data/guides/{images → assets/images}/tab_info.gif +0 -0
- data/guides/{images → assets/images}/tab_note.gif +0 -0
- data/guides/{images → assets/images}/tab_red.gif +0 -0
- data/guides/{images → assets/images}/tab_yellow.gif +0 -0
- data/guides/{images → assets/images}/tab_yellow.png +0 -0
- data/guides/{images → assets/images}/validation_error_messages.png +0 -0
- data/guides/{files → assets}/javascripts/code_highlighter.js +0 -0
- data/guides/{files → assets}/javascripts/guides.js +0 -0
- data/guides/{files → assets}/javascripts/highlighters.js +0 -0
- data/guides/{files → assets}/stylesheets/main.css +26 -15
- data/guides/{files → assets}/stylesheets/print.css +0 -0
- data/guides/{files → assets}/stylesheets/reset.css +0 -0
- data/guides/{files → assets}/stylesheets/style.css +0 -0
- data/guides/{files → assets}/stylesheets/syntax.css +0 -0
- data/guides/rails_guides/generator.rb +79 -29
- data/guides/rails_guides/helpers.rb +2 -2
- data/guides/rails_guides/indexer.rb +24 -11
- data/guides/source/2_2_release_notes.textile +1 -1
- data/guides/source/3_0_release_notes.textile +27 -1
- data/guides/source/action_controller_overview.textile +7 -7
- data/guides/source/action_view_overview.textile +15 -15
- data/guides/source/active_record_querying.textile +4 -3
- data/guides/source/active_support_core_extensions.textile +6 -6
- data/guides/source/activerecord_validations_callbacks.textile +1 -1
- data/guides/source/association_basics.textile +83 -82
- data/guides/source/command_line.textile +16 -12
- data/guides/source/configuring.textile +1 -1
- data/guides/source/contribute.textile +1 -1
- data/guides/source/contributing_to_rails.textile +3 -4
- data/guides/source/credits.html.erb +64 -0
- data/guides/source/debugging_rails_applications.textile +2 -1
- data/guides/source/form_helpers.textile +15 -13
- data/guides/source/getting_started.textile +9 -8
- data/guides/source/index.html.erb +154 -0
- data/guides/source/initialization.textile +4138 -0
- data/guides/source/layout.html.erb +15 -7
- data/guides/source/layouts_and_rendering.textile +6 -5
- data/guides/source/nested_model_forms.textile +3 -3
- data/guides/source/performance_testing.textile +4 -4
- data/guides/source/plugins.textile +15 -14
- data/guides/source/rails_on_rack.textile +1 -1
- data/guides/source/routing.textile +379 -490
- data/guides/source/security.textile +5 -5
- data/guides/source/testing.textile +3 -2
- data/lib/rails.rb +7 -2
- data/lib/rails/application.rb +9 -2
- data/lib/rails/application/configuration.rb +19 -10
- data/lib/rails/application/finisher.rb +4 -0
- data/lib/rails/backtrace_cleaner.rb +1 -1
- data/{bin/rails → lib/rails/cli.rb} +0 -0
- data/lib/rails/commands/runner.rb +1 -1
- data/lib/rails/configuration.rb +12 -0
- data/lib/rails/engine.rb +6 -10
- data/lib/rails/engine/configuration.rb +2 -3
- data/lib/rails/generators.rb +1 -6
- data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +0 -7
- data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +10 -1
- data/lib/rails/generators/erb/scaffold/templates/show.html.erb +2 -0
- data/lib/rails/generators/migration.rb +3 -3
- data/lib/rails/generators/rails/app/app_generator.rb +1 -1
- data/lib/rails/generators/rails/app/templates/Gemfile +2 -0
- data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +1 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +14 -0
- data/lib/rails/generators/rails/app/templates/config/application.rb +4 -1
- data/lib/rails/generators/rails/app/templates/config/boot.rb +5 -13
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +3 -0
- data/lib/rails/generators/rails/app/templates/config/initializers/{cookie_verification_secret.rb.tt → secret_token.rb.tt} +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +1 -3
- data/lib/rails/generators/rails/app/templates/public/index.html +2 -1
- data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +41 -32
- data/lib/rails/generators/rails/app/templates/test/{test_helper.rb → test_helper.rb.tt} +2 -0
- data/lib/rails/generators/rails/model/USAGE +15 -0
- data/lib/rails/generators/rails/stylesheets/templates/scaffold.css +3 -8
- data/lib/rails/paths.rb +17 -5
- data/lib/rails/plugin.rb +1 -1
- data/lib/rails/railtie.rb +3 -25
- data/lib/rails/test_unit/testing.rake +11 -7
- data/lib/rails/version.rb +1 -1
- data/lib/rails/webrick_server.rb +2 -2
- metadata +93 -92
- data/guides/source/credits.textile.erb +0 -60
- data/guides/source/index.textile.erb +0 -139
- data/lib/rails/generators/erb/scaffold/templates/layout.html.erb +0 -17
- data/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory +0 -0
@@ -9,7 +9,7 @@ module RailsGuides
|
|
9
9
|
end
|
10
10
|
|
11
11
|
result << content_tag(:dd, capture(&block))
|
12
|
-
|
12
|
+
result
|
13
13
|
end
|
14
14
|
|
15
15
|
def lh(id, label = "Lighthouse Ticket")
|
@@ -23,7 +23,7 @@ module RailsGuides
|
|
23
23
|
result = content_tag(:img, nil, :src => image, :class => 'left pic', :alt => name)
|
24
24
|
result << content_tag(:h3, name)
|
25
25
|
result << content_tag(:p, capture(&block))
|
26
|
-
|
26
|
+
content_tag(:div, result, :class => 'clearfix', :id => nick)
|
27
27
|
end
|
28
28
|
|
29
29
|
def code(&block)
|
@@ -1,10 +1,14 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
require 'active_support/ordered_hash'
|
3
|
+
|
1
4
|
module RailsGuides
|
2
5
|
class Indexer
|
3
|
-
attr_reader :body, :result, :level_hash
|
6
|
+
attr_reader :body, :result, :warnings, :level_hash
|
4
7
|
|
5
|
-
def initialize(body)
|
6
|
-
@body
|
7
|
-
@result
|
8
|
+
def initialize(body, warnings)
|
9
|
+
@body = body
|
10
|
+
@result = @body.dup
|
11
|
+
@warnings = warnings
|
8
12
|
end
|
9
13
|
|
10
14
|
def index
|
@@ -13,29 +17,30 @@ module RailsGuides
|
|
13
17
|
|
14
18
|
private
|
15
19
|
|
16
|
-
def process(string, current_level=
|
20
|
+
def process(string, current_level=3, counters=[1])
|
17
21
|
s = StringScanner.new(string)
|
18
22
|
|
19
23
|
level_hash = ActiveSupport::OrderedHash.new
|
20
24
|
|
21
25
|
while !s.eos?
|
22
|
-
s
|
26
|
+
re = %r{^h(\d)(?:\((#.*?)\))?\s*\.\s*(.*)$}
|
27
|
+
s.match?(re)
|
23
28
|
if matched = s.matched
|
24
|
-
matched =~
|
25
|
-
level, title = $1.to_i, $2
|
29
|
+
matched =~ re
|
30
|
+
level, idx, title = $1.to_i, $2, $3.strip
|
26
31
|
|
27
32
|
if level < current_level
|
28
33
|
# This is needed. Go figure.
|
29
34
|
return level_hash
|
30
35
|
elsif level == current_level
|
31
36
|
index = counters.join(".")
|
32
|
-
|
37
|
+
idx ||= '#' + title_to_idx(title)
|
33
38
|
|
34
|
-
raise "Parsing Fail" unless @result.sub!(matched, "h#{level}(#{
|
39
|
+
raise "Parsing Fail" unless @result.sub!(matched, "h#{level}(#{idx}). #{index} #{title}")
|
35
40
|
|
36
41
|
key = {
|
37
42
|
:title => title,
|
38
|
-
:id =>
|
43
|
+
:id => idx
|
39
44
|
}
|
40
45
|
# Recurse
|
41
46
|
counters << 1
|
@@ -51,5 +56,13 @@ module RailsGuides
|
|
51
56
|
end
|
52
57
|
level_hash
|
53
58
|
end
|
59
|
+
|
60
|
+
def title_to_idx(title)
|
61
|
+
idx = title.strip.downcase.gsub(/\s+|_/, '-').delete('^a-z0-9-').sub(/^[^a-z]*/, '')
|
62
|
+
if warnings && idx.blank?
|
63
|
+
puts "BLANK ID: please put an explicit ID for section #{title}, as in h5(#my-id)"
|
64
|
+
end
|
65
|
+
idx
|
66
|
+
end
|
54
67
|
end
|
55
68
|
end
|
@@ -385,7 +385,7 @@ You can unpack or install a single gem by specifying +GEM=_gem_name_+ on the com
|
|
385
385
|
h4. Other Railties Changes
|
386
386
|
|
387
387
|
* If you're a fan of the "Thin":http://code.macournoyer.com/thin/ web server, you'll be happy to know that +script/server+ now supports Thin directly.
|
388
|
-
* +script/plugin install
|
388
|
+
* +script/plugin install <plugin> -r <revision>+ now works with git-based as well as svn-based plugins.
|
389
389
|
* +script/console+ now supports a +--debugger+ option
|
390
390
|
* Instructions for setting up a continuous integration server to build Rails itself are included in the Rails source
|
391
391
|
* +rake notes:custom ANNOTATION=MYFLAG+ lets you list out custom annotations.
|
@@ -302,9 +302,11 @@ More Information:
|
|
302
302
|
|
303
303
|
h4. Action View
|
304
304
|
|
305
|
+
h5. Unobtrusive JavaScript
|
306
|
+
|
305
307
|
Major re-write was done in the Action View helpers, implementing Unobtrusive JavaScript (UJS) hooks and removing the old inline AJAX commands. This enables Rails to use any compliant UJS driver to implement the UJS hooks in the helpers.
|
306
308
|
|
307
|
-
What this means is that all previous <tt>remote_
|
309
|
+
What this means is that all previous <tt>remote_<method></tt> helpers have been removed from Rails core and put into the "Prototype Legacy Helper":http://github.com/rails/prototype_legacy_helper. To get UJS hooks into your HTML, you now pass <tt>:remote => true</tt> instead. For example:
|
308
310
|
|
309
311
|
<ruby>
|
310
312
|
form_for @post, :remote => true
|
@@ -316,6 +318,22 @@ Produces:
|
|
316
318
|
<form action="http://host.com" id="create-post" method="post" data-remote="true">
|
317
319
|
</html>
|
318
320
|
|
321
|
+
h5. Helpers with Blocks
|
322
|
+
|
323
|
+
Helpers like +form_for+ or +div_for+ that insert content from a block use +<%=+ now:
|
324
|
+
|
325
|
+
<erb>
|
326
|
+
<%= form_for @post do |f| %>
|
327
|
+
...
|
328
|
+
<% end %>
|
329
|
+
</erb>
|
330
|
+
|
331
|
+
Your own helpers of that kind are expected to return a string, rather than appending to the output buffer by hand.
|
332
|
+
|
333
|
+
Helpers that do something else, like +cache+ or +content_for+, are not affected by this change, they need +<%+ as before.
|
334
|
+
|
335
|
+
h5. Other Changes
|
336
|
+
|
319
337
|
* You no longer need to call <tt>h(string)</tt> to escape HTML output, it is on by default in all view templates. If you want the unescaped string, call <tt>raw(string)</tt>.
|
320
338
|
* Helpers now output HTML 5 by default.
|
321
339
|
* Form label helper now pulls values from I18n with a single value, so <tt>f.label :name</tt> will pull the <tt>:name</tt> translation.
|
@@ -382,6 +400,13 @@ class Person < ActiveRecord::Base
|
|
382
400
|
end
|
383
401
|
</ruby>
|
384
402
|
|
403
|
+
There's also support for introspection:
|
404
|
+
|
405
|
+
<ruby>
|
406
|
+
User.validators
|
407
|
+
User.validators_on(:login)
|
408
|
+
</ruby>
|
409
|
+
|
385
410
|
More Information:
|
386
411
|
* "Sexy Validation in Rails 3":http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/
|
387
412
|
* "Rails 3 Validations Explained":http://lindsaar.net/2010/1/31/validates_rails_3_awesome_is_true
|
@@ -512,6 +537,7 @@ These are the main changes in Active Support:
|
|
512
537
|
* <tt>MissingSourceFile</tt> exists as a constant but it is now just equals to <tt>LoadError</tt>.
|
513
538
|
* Added <tt>Class#class_attribute</tt>, to be able to declare a class-level attribute whose value is inheritable and overwritable by subclasses.
|
514
539
|
* Finally removed +DeprecatedCallbacks+ in <tt>ActiveRecord::Associations</tt>.
|
540
|
+
* +Object#metaclass+ is now +Kernel#singleton_class+ to match Ruby.
|
515
541
|
|
516
542
|
The following methods have been removed because they are now available in Ruby 1.8.7 and 1.9.
|
517
543
|
|
@@ -255,12 +255,12 @@ The +destroy+ action redirects to the application's +root_url+, where the messag
|
|
255
255
|
<html>
|
256
256
|
<!-- <head/> -->
|
257
257
|
<body>
|
258
|
-
<% if flash[:notice]
|
258
|
+
<% if flash[:notice] %>
|
259
259
|
<p class="notice"><%= flash[:notice] %></p>
|
260
|
-
<% end
|
261
|
-
<% if flash[:error]
|
260
|
+
<% end %>
|
261
|
+
<% if flash[:error] %>
|
262
262
|
<p class="error"><%= flash[:error] %></p>
|
263
|
-
<% end
|
263
|
+
<% end %>
|
264
264
|
<!-- more content -->
|
265
265
|
</body>
|
266
266
|
</html>
|
@@ -492,10 +492,10 @@ The way this is done is to add a non-guessable token which is only known to your
|
|
492
492
|
If you generate a form like this:
|
493
493
|
|
494
494
|
<ruby>
|
495
|
-
|
495
|
+
<%= form_for @user do |f| %>
|
496
496
|
<%= f.text_field :username %>
|
497
|
-
<%= f.text_field :password
|
498
|
-
<% end
|
497
|
+
<%= f.text_field :password %>
|
498
|
+
<% end %>
|
499
499
|
</ruby>
|
500
500
|
|
501
501
|
You will see how the token gets added as a hidden field:
|
@@ -135,7 +135,7 @@ The +post+ partial wraps the post's +body+ in a +div+ with the +id+ of the post
|
|
135
135
|
*posts/_post.html.erb*
|
136
136
|
|
137
137
|
<ruby>
|
138
|
-
|
138
|
+
<%= div_for(post) do %>
|
139
139
|
<p><%= post.body %></p>
|
140
140
|
<% end %>
|
141
141
|
</ruby>
|
@@ -158,7 +158,7 @@ You can also render a block of code within a partial layout instead of calling +
|
|
158
158
|
|
159
159
|
<ruby>
|
160
160
|
<% render(:layout => 'box', :locals => {:post => @post}) do %>
|
161
|
-
|
161
|
+
<%= div_for(post) do %>
|
162
162
|
<p><%= post.body %></p>
|
163
163
|
<% end %>
|
164
164
|
<% end %>
|
@@ -654,7 +654,7 @@ The core method of this helper, form_for, gives you the ability to create a form
|
|
654
654
|
|
655
655
|
<ruby>
|
656
656
|
# Note: a @person variable will have been created in the controller (e.g. @person = Person.new)
|
657
|
-
|
657
|
+
<%= form_for :person, @person, :url => { :action => "create" } do |f| %>
|
658
658
|
<%= f.text_field :first_name %>
|
659
659
|
<%= f.text_field :last_name %>
|
660
660
|
<%= submit_tag 'Create' %>
|
@@ -695,7 +695,7 @@ h5. fields_for
|
|
695
695
|
Creates a scope around a specific model object like form_for, but doesn‘t create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form:
|
696
696
|
|
697
697
|
<ruby>
|
698
|
-
|
698
|
+
<%= form_for @person, :url => { :action => "update" } do |person_form| %>
|
699
699
|
First name: <%= person_form.text_field :first_name %>
|
700
700
|
Last name : <%= person_form.text_field :last_name %>
|
701
701
|
|
@@ -719,7 +719,7 @@ h5. form_for
|
|
719
719
|
Creates a form and a scope around a specific model object that is used as a base for questioning about values for the fields.
|
720
720
|
|
721
721
|
<ruby>
|
722
|
-
|
722
|
+
<%= form_for @post do |f| %>
|
723
723
|
<%= f.label :title, 'Title' %>:
|
724
724
|
<%= f.text_field :title %><br />
|
725
725
|
<%= f.label :body, 'Body' %>:
|
@@ -957,7 +957,7 @@ h5. field_set_tag
|
|
957
957
|
Creates a field set for grouping HTML form elements.
|
958
958
|
|
959
959
|
<ruby>
|
960
|
-
|
960
|
+
<%= field_set_tag do %>
|
961
961
|
<p><%= text_field_tag 'name' %></p>
|
962
962
|
<% end %>
|
963
963
|
# => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>
|
@@ -970,10 +970,10 @@ Creates a file upload field.
|
|
970
970
|
If you are using file uploads then you will also need to set the multipart option for the form tag:
|
971
971
|
|
972
972
|
<ruby>
|
973
|
-
<%= form_tag { :action => "post" }, { :multipart => true } %>
|
973
|
+
<%= form_tag { :action => "post" }, { :multipart => true } do %>
|
974
974
|
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
|
975
975
|
<%= submit_tag %>
|
976
|
-
|
976
|
+
<% end %>
|
977
977
|
</ruby>
|
978
978
|
|
979
979
|
Example output:
|
@@ -988,9 +988,9 @@ h5. form_tag
|
|
988
988
|
Starts a form tag that points the action to an url configured with +url_for_options+ just like +ActionController::Base#url_for+.
|
989
989
|
|
990
990
|
<ruby>
|
991
|
-
|
991
|
+
<%= form_tag '/posts' do %>
|
992
992
|
<div><%= submit_tag 'Save' %></div>
|
993
|
-
<% end
|
993
|
+
<% end %>
|
994
994
|
# => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
|
995
995
|
</ruby>
|
996
996
|
|
@@ -1079,7 +1079,7 @@ h4. JavaScriptHelper
|
|
1079
1079
|
|
1080
1080
|
Provides functionality for working with JavaScript in your views.
|
1081
1081
|
|
1082
|
-
Rails includes the Prototype JavaScript framework and the Scriptaculous JavaScript controls and visual effects library. If you wish to use these libraries and their helpers, make sure
|
1082
|
+
Rails includes the Prototype JavaScript framework and the Scriptaculous JavaScript controls and visual effects library. If you wish to use these libraries and their helpers, make sure +<%= javascript_include_tag :defaults, :cache => true %>+ is in the HEAD section of your page. This function will include the necessary JavaScript files Rails generated in the public/javascripts directory.
|
1083
1083
|
|
1084
1084
|
h5. button_to_function
|
1085
1085
|
|
@@ -1251,7 +1251,7 @@ h5. remote_form_for
|
|
1251
1251
|
Creates a form that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement and a scope around a specific resource that is used as a base for questioning about values for the fields.
|
1252
1252
|
|
1253
1253
|
<ruby>
|
1254
|
-
|
1254
|
+
<%= remote_form_for(@post) do |f| %>
|
1255
1255
|
...
|
1256
1256
|
<% end %>
|
1257
1257
|
</ruby>
|
@@ -1304,7 +1304,7 @@ h4. PrototypeHelper::JavaScriptGenerator::GeneratorMethods
|
|
1304
1304
|
|
1305
1305
|
JavaScriptGenerator generates blocks of JavaScript code that allow you to change the content and presentation of multiple DOM elements. Use this in your Ajax response bodies, either in a +script+ tag or as plain JavaScript sent with a Content-type of "text/javascript".
|
1306
1306
|
|
1307
|
-
h5. <<
|
1307
|
+
h5(#push). <<
|
1308
1308
|
|
1309
1309
|
Writes raw JavaScript to the page.
|
1310
1310
|
|
@@ -1312,7 +1312,7 @@ Writes raw JavaScript to the page.
|
|
1312
1312
|
page << "alert('JavaScript with Prototype.');"
|
1313
1313
|
</ruby>
|
1314
1314
|
|
1315
|
-
h5. []
|
1315
|
+
h5(#at). []
|
1316
1316
|
|
1317
1317
|
Returns a element reference by finding it through it's id in the DOM.
|
1318
1318
|
|
@@ -1414,7 +1414,7 @@ Replaces the inner HTML of the DOM element with the given id.
|
|
1414
1414
|
page.replace_html 'person-45', :partial => 'person', :object => @person
|
1415
1415
|
</ruby>
|
1416
1416
|
|
1417
|
-
h5. select
|
1417
|
+
h5(#prototype-select). select
|
1418
1418
|
|
1419
1419
|
Returns a collection reference by finding it through a CSS pattern in the DOM.
|
1420
1420
|
|
@@ -274,7 +274,7 @@ Client.where(
|
|
274
274
|
|
275
275
|
This makes for clearer readability if you have a large number of variable conditions.
|
276
276
|
|
277
|
-
h5. Range Conditions
|
277
|
+
h5(#array-range_conditions). Range Conditions
|
278
278
|
|
279
279
|
If you're looking for a range inside of a table (for example, users created in a certain timeframe) you can use the conditions option coupled with the +IN+ SQL statement for this. If you had two dates coming in from a controller you could do something like this to look for a range:
|
280
280
|
|
@@ -353,7 +353,7 @@ The field name does not have to be a symbol it can also be a string:
|
|
353
353
|
Client.where({ 'locked' => true })
|
354
354
|
</ruby>
|
355
355
|
|
356
|
-
h5. Range Conditions
|
356
|
+
h5(#hash-range_conditions). Range Conditions
|
357
357
|
|
358
358
|
The good thing about this is that we can pass in a range for our fields without it generating a large query as shown in the preamble of this section.
|
359
359
|
|
@@ -742,7 +742,7 @@ end
|
|
742
742
|
The above code will execute just <strong>2</strong> queries, as opposed to <strong>11</strong> queries in the previous case:
|
743
743
|
|
744
744
|
<sql>
|
745
|
-
SELECT * FROM clients
|
745
|
+
SELECT * FROM clients LIMIT 10
|
746
746
|
SELECT addresses.* FROM addresses
|
747
747
|
WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))
|
748
748
|
</sql>
|
@@ -934,6 +934,7 @@ h3. Changelog
|
|
934
934
|
|
935
935
|
"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/16
|
936
936
|
|
937
|
+
* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
|
937
938
|
* February 3, 2010: Update to Rails 3 by "James Miller":credits.html#bensie
|
938
939
|
* February 7, 2009: Second version by "Pratik":credits.html#lifo
|
939
940
|
* December 29 2008: Initial version by "Ryan Bigg":credits.html#radar
|
@@ -210,9 +210,9 @@ String.new.singleton_class # => #<Class:#<String:0x17a1d1c>>
|
|
210
210
|
</ruby>
|
211
211
|
|
212
212
|
WARNING: Fixnums and symbols have no singleton classes, +singleton_class+
|
213
|
-
raises +TypeError+ on them.
|
213
|
+
raises +TypeError+ on them. Moreover, the singleton classes of +nil+, +true+, and +false+, are +NilClass+, +TrueClass+, and +FalseClass+, respectively.
|
214
214
|
|
215
|
-
NOTE: Defined in +active_support/core_ext/
|
215
|
+
NOTE: Defined in +active_support/core_ext/kernel/singleton_class.rb+.
|
216
216
|
|
217
217
|
h4. +class_eval(*args, &block)+
|
218
218
|
|
@@ -233,7 +233,7 @@ class Proc
|
|
233
233
|
end
|
234
234
|
</ruby>
|
235
235
|
|
236
|
-
NOTE: Defined in +active_support/core_ext/
|
236
|
+
NOTE: Defined in +active_support/core_ext/kernel/singleton_class.rb+.
|
237
237
|
|
238
238
|
h4. +acts_like?(duck)+
|
239
239
|
|
@@ -866,7 +866,7 @@ WARNING: Note that in that case +parent+ returns +Object+.
|
|
866
866
|
|
867
867
|
NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
|
868
868
|
|
869
|
-
h5. +parents+
|
869
|
+
h5(#module-parents). +parents+
|
870
870
|
|
871
871
|
The method +parents+ calls +parent+ on the receiver and upwards until +Object+ is reached. The chain is returned in an array, from bottom to top:
|
872
872
|
|
@@ -2191,9 +2191,9 @@ NOTE: Defined in +active_support/core_ext/array/grouping.rb+.
|
|
2191
2191
|
|
2192
2192
|
h3. Extensions to +Hash+
|
2193
2193
|
|
2194
|
-
h4. Conversions
|
2194
|
+
h4(#hash-conversions). Conversions
|
2195
2195
|
|
2196
|
-
h5. +to_xml+
|
2196
|
+
h5(#hash-to-xml). +to_xml+
|
2197
2197
|
|
2198
2198
|
The method +to_xml+ returns a string containing an XML representation of its receiver:
|
2199
2199
|
|
@@ -417,7 +417,7 @@ h5. Creating Join Tables for +has_and_belongs_to_many+ Associations
|
|
417
417
|
|
418
418
|
If you create a +has_and_belongs_to_many+ association, you need to explicitly create the joining table. Unless the name of the join table is explicitly specified by using the +:join_table+ option, Active Record creates the name by using the lexical order of the class names. So a join between customer and order models will give the default join table name of "customers_orders" because "c" outranks "o" in lexical ordering.
|
419
419
|
|
420
|
-
WARNING: The precedence between model names is calculated using the
|
420
|
+
WARNING: The precedence between model names is calculated using the +<+ operator for +String+. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers" (because the underscore '_' is lexicographically _less_ than 's' in common encodings).
|
421
421
|
|
422
422
|
Whatever the name, you must manually generate the join table with an appropriate migration. For example, consider these associations:
|
423
423
|
|
@@ -603,11 +603,11 @@ The +belongs_to+ association supports these options:
|
|
603
603
|
* +:touch+
|
604
604
|
* +:validate+
|
605
605
|
|
606
|
-
h6. +:autosave+
|
606
|
+
h6(#belongs_to-autosave). +:autosave+
|
607
607
|
|
608
608
|
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
|
609
609
|
|
610
|
-
h6. +:class_name+
|
610
|
+
h6(#belongs_to-class_name). +:class_name+
|
611
611
|
|
612
612
|
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if an order belongs to a customer, but the actual name of the model containing customers is +Patron+, you'd set things up this way:
|
613
613
|
|
@@ -617,7 +617,7 @@ class Order < ActiveRecord::Base
|
|
617
617
|
end
|
618
618
|
</ruby>
|
619
619
|
|
620
|
-
h6. +:conditions+
|
620
|
+
h6(#belongs_to-conditions). +:conditions+
|
621
621
|
|
622
622
|
The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL +WHERE+ clause).
|
623
623
|
|
@@ -666,13 +666,13 @@ end
|
|
666
666
|
|
667
667
|
Counter cache columns are added to the containing model's list of read-only attributes through +attr_readonly+.
|
668
668
|
|
669
|
-
h6. +:dependent+
|
669
|
+
h6(#belongs_to-dependent). +:dependent+
|
670
670
|
|
671
671
|
If you set the +:dependent+ option to +:destroy+, then deleting this object will call the +destroy+ method on the associated object to delete that object. If you set the +:dependent+ option to +:delete+, then deleting this object will delete the associated object _without_ calling its +destroy+ method.
|
672
672
|
|
673
673
|
WARNING: You should not specify this option on a +belongs_to+ association that is connected with a +has_many+ association on the other class. Doing so can lead to orphaned records in your database.
|
674
674
|
|
675
|
-
h6. +:foreign_key+
|
675
|
+
h6(#belongs_to-foreign_key). +:foreign_key+
|
676
676
|
|
677
677
|
By convention, Rails guesses that the column used to hold the foreign key on this model is the name of the association with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
|
678
678
|
|
@@ -685,7 +685,7 @@ end
|
|
685
685
|
|
686
686
|
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
|
687
687
|
|
688
|
-
h6. +:include+
|
688
|
+
h6(#belongs_to-includes). +:include+
|
689
689
|
|
690
690
|
You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
|
691
691
|
|
@@ -727,11 +727,11 @@ h6. +:polymorphic+
|
|
727
727
|
|
728
728
|
Passing +true+ to the +:polymorphic+ option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.
|
729
729
|
|
730
|
-
h6. +:readonly+
|
730
|
+
h6(#belongs_to-readonly). +:readonly+
|
731
731
|
|
732
732
|
If you set the +:readonly+ option to +true+, then the associated object will be read-only when retrieved via the association.
|
733
733
|
|
734
|
-
h6. +:select+
|
734
|
+
h6(#belongs_to-select). +:select+
|
735
735
|
|
736
736
|
The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
|
737
737
|
|
@@ -759,11 +759,11 @@ class Order < ActiveRecord::Base
|
|
759
759
|
end
|
760
760
|
</ruby>
|
761
761
|
|
762
|
-
h6. +:validate+
|
762
|
+
h6(#belongs_to-validate). +:validate+
|
763
763
|
|
764
764
|
If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
|
765
765
|
|
766
|
-
h5. How To Know Whether There's an Associated Object?
|
766
|
+
h5(#belongs_to-how_to_know_whether_theres_an_associated_object). How To Know Whether There's an Associated Object?
|
767
767
|
|
768
768
|
To know whether there's and associated object just check <tt><em>association</em>.nil?</tt>:
|
769
769
|
|
@@ -773,7 +773,7 @@ if @order.customer.nil?
|
|
773
773
|
end
|
774
774
|
</ruby>
|
775
775
|
|
776
|
-
h5. When are Objects Saved?
|
776
|
+
h5(#belongs_to-when_are_objects_saved). When are Objects Saved?
|
777
777
|
|
778
778
|
Assigning an object to a +belongs_to+ association does _not_ automatically save the object. It does not save the associated object either.
|
779
779
|
|
@@ -869,15 +869,15 @@ The +has_one+ association supports these options:
|
|
869
869
|
* +:through+
|
870
870
|
* +:validate+
|
871
871
|
|
872
|
-
h6. +:as+
|
872
|
+
h6(#has_one-as). +:as+
|
873
873
|
|
874
874
|
Setting the +:as+ option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.
|
875
875
|
|
876
|
-
h6. +:autosave+
|
876
|
+
h6(#has_one-autosave). +:autosave+
|
877
877
|
|
878
878
|
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
|
879
879
|
|
880
|
-
h6. +:class_name+
|
880
|
+
h6(#has_one-class_name). +:class_name+
|
881
881
|
|
882
882
|
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if a supplier has an account, but the actual name of the model containing accounts is +Billing+, you'd set things up this way:
|
883
883
|
|
@@ -887,7 +887,7 @@ class Supplier < ActiveRecord::Base
|
|
887
887
|
end
|
888
888
|
</ruby>
|
889
889
|
|
890
|
-
h6. +:conditions+
|
890
|
+
h6(#has_one-conditions). +:conditions+
|
891
891
|
|
892
892
|
The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL +WHERE+ clause).
|
893
893
|
|
@@ -897,11 +897,11 @@ class Supplier < ActiveRecord::Base
|
|
897
897
|
end
|
898
898
|
</ruby>
|
899
899
|
|
900
|
-
h6. +:dependent+
|
900
|
+
h6(#has_one-dependent). +:dependent+
|
901
901
|
|
902
902
|
If you set the +:dependent+ option to +:destroy+, then deleting this object will call the +destroy+ method on the associated object to delete that object. If you set the +:dependent+ option to +:delete+, then deleting this object will delete the associated object _without_ calling its +destroy+ method. If you set the +:dependent+ option to +:nullify+, then deleting this object will set the foreign key in the association object to +NULL+.
|
903
903
|
|
904
|
-
h6. +:foreign_key+
|
904
|
+
h6(#has_one-foreign_key). +:foreign_key+
|
905
905
|
|
906
906
|
By convention, Rails guesses that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
|
907
907
|
|
@@ -913,7 +913,7 @@ end
|
|
913
913
|
|
914
914
|
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
|
915
915
|
|
916
|
-
h6. +:include+
|
916
|
+
h6(#has_one-include). +:include+
|
917
917
|
|
918
918
|
You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
|
919
919
|
|
@@ -949,39 +949,39 @@ class Representative < ActiveRecord::Base
|
|
949
949
|
end
|
950
950
|
</ruby>
|
951
951
|
|
952
|
-
h6. +:order+
|
952
|
+
h6(#has_one-order). +:order+
|
953
953
|
|
954
954
|
The +:order+ option dictates the order in which associated objects will be received (in the syntax used by a SQL +ORDER BY+ clause). Because a +has_one+ association will only retrieve a single associated object, this option should not be needed.
|
955
955
|
|
956
|
-
h6. +:primary_key+
|
956
|
+
h6(#has_one-primary_key). +:primary_key+
|
957
957
|
|
958
958
|
By convention, Rails guesses that the column used to hold the primary key of this model is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
|
959
959
|
|
960
|
-
h6. +:readonly+
|
960
|
+
h6(#has_one-readonly). +:readonly+
|
961
961
|
|
962
962
|
If you set the +:readonly+ option to +true+, then the associated object will be read-only when retrieved via the association.
|
963
963
|
|
964
|
-
h6. +:select+
|
964
|
+
h6(#has_one-select). +:select+
|
965
965
|
|
966
966
|
The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
|
967
967
|
|
968
|
-
h6. +:source+
|
968
|
+
h6(#has_one-source). +:source+
|
969
969
|
|
970
970
|
The +:source+ option specifies the source association name for a +has_one :through+ association.
|
971
971
|
|
972
|
-
h6. +:source_type+
|
972
|
+
h6(#has_one-source_type). +:source_type+
|
973
973
|
|
974
974
|
The +:source_type+ option specifies the source association type for a +has_one :through+ association that proceeds through a polymorphic association.
|
975
975
|
|
976
|
-
h6. +:through+
|
976
|
+
h6(#has_one-through). +:through+
|
977
977
|
|
978
978
|
The +:through+ option specifies a join model through which to perform the query. +has_one :through+ associations were discussed in detail <a href="#the-has-one-through-association">earlier in this guide</a>.
|
979
979
|
|
980
|
-
h6. +:validate+
|
980
|
+
h6(#has_one-validate). +:validate+
|
981
981
|
|
982
982
|
If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
|
983
983
|
|
984
|
-
h5. How To Know Whether There's an Associated Object?
|
984
|
+
h5(#has_one-how_to_know_whether_theres_an_associated_object). How To Know Whether There's an Associated Object?
|
985
985
|
|
986
986
|
To know whether there's and associated object just check <tt><em>association</em>.nil?</tt>:
|
987
987
|
|
@@ -991,7 +991,7 @@ if @supplier.account.nil?
|
|
991
991
|
end
|
992
992
|
</ruby>
|
993
993
|
|
994
|
-
h5. When are Objects Saved?
|
994
|
+
h5(#has_one-when_are_objects_saved). When are Objects Saved?
|
995
995
|
|
996
996
|
When you assign an object to a +has_one+ association, that object is automatically saved (in order to update its foreign key). In addition, any object being replaced is also automatically saved, because its foreign key will change too.
|
997
997
|
|
@@ -1005,7 +1005,7 @@ h4. +has_many+ Association Reference
|
|
1005
1005
|
|
1006
1006
|
The +has_many+ association creates a one-to-many relationship with another model. In database terms, this association says that the other class will have a foreign key that refers to instances of this class.
|
1007
1007
|
|
1008
|
-
h5. Methods Added
|
1008
|
+
h5. Methods Added by +has_many+
|
1009
1009
|
|
1010
1010
|
When you declare a +has_many+ association, the declaring class automatically gains 13 methods related to the association:
|
1011
1011
|
|
@@ -1049,7 +1049,7 @@ orders.build(attributes = {}, ...)
|
|
1049
1049
|
orders.create(attributes = {})
|
1050
1050
|
</ruby>
|
1051
1051
|
|
1052
|
-
h6. <tt><em>collection</em>(force_reload = false)</tt>
|
1052
|
+
h6(#has_many-collection). <tt><em>collection</em>(force_reload = false)</tt>
|
1053
1053
|
|
1054
1054
|
The <tt><em>collection</em></tt> method returns an array of all of the associated objects. If there are no associated objects, it returns an empty array.
|
1055
1055
|
|
@@ -1057,7 +1057,7 @@ The <tt><em>collection</em></tt> method returns an array of all of the associate
|
|
1057
1057
|
@orders = @customer.orders
|
1058
1058
|
</ruby>
|
1059
1059
|
|
1060
|
-
h6. <tt><em>collection</em><<(object, ...)</tt>
|
1060
|
+
h6(#has_many-collection-lt_lt). <tt><em>collection</em><<(object, ...)</tt>
|
1061
1061
|
|
1062
1062
|
The <tt><em>collection</em><<</tt> method adds one or more objects to the collection by setting their foreign keys to the primary key of the calling model.
|
1063
1063
|
|
@@ -1065,7 +1065,7 @@ The <tt><em>collection</em><<</tt> method adds one or more objects to the collec
|
|
1065
1065
|
@customer.orders << @order1
|
1066
1066
|
</ruby>
|
1067
1067
|
|
1068
|
-
h6. <tt><em>collection</em>.delete(object, ...)</tt>
|
1068
|
+
h6(#has_many-collection-delete). <tt><em>collection</em>.delete(object, ...)</tt>
|
1069
1069
|
|
1070
1070
|
The <tt><em>collection</em>.delete</tt> method removes one or more objects from the collection by setting their foreign keys to +NULL+.
|
1071
1071
|
|
@@ -1076,11 +1076,11 @@ The <tt><em>collection</em>.delete</tt> method removes one or more objects from
|
|
1076
1076
|
WARNING: Objects will be in addition destroyed if they're associated with +:dependent => :destroy+, and deleted if they're associated with +:dependent => :delete_all+.
|
1077
1077
|
|
1078
1078
|
|
1079
|
-
h6. <tt><em>collection</em>=objects</tt>
|
1079
|
+
h6(#has_many-collection_equal). <tt><em>collection</em>=objects</tt>
|
1080
1080
|
|
1081
1081
|
The <tt><em>collection</em>=</tt> method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
|
1082
1082
|
|
1083
|
-
h6. <tt><em>collection_singular</em>_ids</tt>
|
1083
|
+
h6(#has_many-collection_singular). <tt><em>collection_singular</em>_ids</tt>
|
1084
1084
|
|
1085
1085
|
The <tt><em>collection_singular</em>_ids</tt> method returns an array of the ids of the objects in the collection.
|
1086
1086
|
|
@@ -1088,11 +1088,11 @@ The <tt><em>collection_singular</em>_ids</tt> method returns an array of the ids
|
|
1088
1088
|
@order_ids = @customer.order_ids
|
1089
1089
|
</ruby>
|
1090
1090
|
|
1091
|
-
h6. <tt><em>collection_singular</em>_ids=ids</tt>
|
1091
|
+
h6(#has_many-collection_singular_ids_ids). <tt><em>collection_singular</em>_ids=ids</tt>
|
1092
1092
|
|
1093
1093
|
The <tt><em>collection_singular</em>_ids=</tt> method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
|
1094
1094
|
|
1095
|
-
h6. <tt><em>collection</em>.clear</tt>
|
1095
|
+
h6(#has_many-collection_clear). <tt><em>collection</em>.clear</tt>
|
1096
1096
|
|
1097
1097
|
The <tt><em>collection</em>.clear</tt> method removes every object from the collection. This destroys the associated objects if they are associated with +:dependent => :destroy+, deletes them directly from the database if +:dependent => :delete_all+, and otherwise sets their foreign keys to +NULL+.
|
1098
1098
|
|
@@ -1179,7 +1179,7 @@ The +has_many+ association supports these options:
|
|
1179
1179
|
* +:uniq+
|
1180
1180
|
* +:validate+
|
1181
1181
|
|
1182
|
-
h6. +:as+
|
1182
|
+
h6(#has_many-as). +:as+
|
1183
1183
|
|
1184
1184
|
Setting the +:as+ option indicates that this is a polymorphic association, as discussed <a href="#polymorphic-associations">earlier in this guide</a>.
|
1185
1185
|
|
@@ -1187,7 +1187,7 @@ h6. +:autosave+
|
|
1187
1187
|
|
1188
1188
|
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
|
1189
1189
|
|
1190
|
-
h6. +:class_name+
|
1190
|
+
h6(#has_many-class_name). +:class_name+
|
1191
1191
|
|
1192
1192
|
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if a customer has many orders, but the actual name of the model containing orders is +Transaction+, you'd set things up this way:
|
1193
1193
|
|
@@ -1197,7 +1197,7 @@ class Customer < ActiveRecord::Base
|
|
1197
1197
|
end
|
1198
1198
|
</ruby>
|
1199
1199
|
|
1200
|
-
h6. +:conditions+
|
1200
|
+
h6(#has_many-conditions). +:conditions+
|
1201
1201
|
|
1202
1202
|
The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL +WHERE+ clause).
|
1203
1203
|
|
@@ -1230,27 +1230,27 @@ end
|
|
1230
1230
|
|
1231
1231
|
Be sure to use single quotes.
|
1232
1232
|
|
1233
|
-
h6. +:counter_sql+
|
1233
|
+
h6(#has_many-counter_sql). +:counter_sql+
|
1234
1234
|
|
1235
1235
|
Normally Rails automatically generates the proper SQL to count the association members. With the +:counter_sql+ option, you can specify a complete SQL statement to count them yourself.
|
1236
1236
|
|
1237
1237
|
NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting +SELECT COUNT(*) FROM+ for the +SELECT ... FROM+ clause of your +:finder_sql+ statement.
|
1238
1238
|
|
1239
|
-
h6. +:dependent+
|
1239
|
+
h6(#has_many-dependent). +:dependent+
|
1240
1240
|
|
1241
1241
|
If you set the +:dependent+ option to +:destroy+, then deleting this object will call the +destroy+ method on the associated objects to delete those objects. If you set the +:dependent+ option to +:delete_all+, then deleting this object will delete the associated objects _without_ calling their +destroy+ method. If you set the +:dependent+ option to +:nullify+, then deleting this object will set the foreign key in the associated objects to +NULL+.
|
1242
1242
|
|
1243
1243
|
NOTE: This option is ignored when you use the +:through+ option on the association.
|
1244
1244
|
|
1245
|
-
h6. +:extend+
|
1245
|
+
h6(#has_many-extend). +:extend+
|
1246
1246
|
|
1247
1247
|
The +:extend+ option specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
|
1248
1248
|
|
1249
|
-
h6. +:finder_sql+
|
1249
|
+
h6(#has_many-finder_sql). +:finder_sql+
|
1250
1250
|
|
1251
1251
|
Normally Rails automatically generates the proper SQL to fetch the association members. With the +:finder_sql+ option, you can specify a complete SQL statement to fetch them yourself. If fetching objects requires complex multi-table SQL, this may be necessary.
|
1252
1252
|
|
1253
|
-
h6. +:foreign_key+
|
1253
|
+
h6(#has_many-foreign_key). +:foreign_key+
|
1254
1254
|
|
1255
1255
|
By convention, Rails guesses that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
|
1256
1256
|
|
@@ -1262,7 +1262,7 @@ end
|
|
1262
1262
|
|
1263
1263
|
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
|
1264
1264
|
|
1265
|
-
h6. +:group+
|
1265
|
+
h6(:has_many-group). +:group+
|
1266
1266
|
|
1267
1267
|
The +:group+ option supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
|
1268
1268
|
|
@@ -1272,7 +1272,7 @@ class Customer < ActiveRecord::Base
|
|
1272
1272
|
end
|
1273
1273
|
</ruby>
|
1274
1274
|
|
1275
|
-
h6. +:include+
|
1275
|
+
h6(#has_many-include). +:include+
|
1276
1276
|
|
1277
1277
|
You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
|
1278
1278
|
|
@@ -1308,7 +1308,7 @@ class LineItem < ActiveRecord::Base
|
|
1308
1308
|
end
|
1309
1309
|
</ruby>
|
1310
1310
|
|
1311
|
-
h6. +:limit+
|
1311
|
+
h6(#has_many-limit). +:limit+
|
1312
1312
|
|
1313
1313
|
The +:limit+ option lets you restrict the total number of objects that will be fetched through an association.
|
1314
1314
|
|
@@ -1319,11 +1319,11 @@ class Customer < ActiveRecord::Base
|
|
1319
1319
|
end
|
1320
1320
|
</ruby>
|
1321
1321
|
|
1322
|
-
h6. +:offset+
|
1322
|
+
h6(#has_many-offset). +:offset+
|
1323
1323
|
|
1324
1324
|
The +:offset+ option lets you specify the starting offset for fetching objects via an association. For example, if you set +:offset => 11+, it will skip the first 11 records.
|
1325
1325
|
|
1326
|
-
h6. +:order+
|
1326
|
+
h6(#has_many-order). +:order+
|
1327
1327
|
|
1328
1328
|
The +:order+ option dictates the order in which associated objects will be received (in the syntax used by a SQL +ORDER BY+ clause).
|
1329
1329
|
|
@@ -1333,41 +1333,41 @@ class Customer < ActiveRecord::Base
|
|
1333
1333
|
end
|
1334
1334
|
</ruby>
|
1335
1335
|
|
1336
|
-
h6. +:primary_key+
|
1336
|
+
h6(#has_many-primary_key). +:primary_key+
|
1337
1337
|
|
1338
1338
|
By convention, Rails guesses that the column used to hold the primary key of the association is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
|
1339
1339
|
|
1340
|
-
h6. +:readonly+
|
1340
|
+
h6(#has_many-readonly). +:readonly+
|
1341
1341
|
|
1342
1342
|
If you set the +:readonly+ option to +true+, then the associated objects will be read-only when retrieved via the association.
|
1343
1343
|
|
1344
|
-
h6. +:select+
|
1344
|
+
h6(#has_many-select). +:select+
|
1345
1345
|
|
1346
1346
|
The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
|
1347
1347
|
|
1348
1348
|
WARNING: If you specify your own +:select+, be sure to include the primary key and foreign key columns of the associated model. If you do not, Rails will throw an error.
|
1349
1349
|
|
1350
|
-
h6. +:source+
|
1350
|
+
h6(#has_many-source). +:source+
|
1351
1351
|
|
1352
1352
|
The +:source+ option specifies the source association name for a +has_many :through+ association. You only need to use this option if the name of the source association cannot be automatically inferred from the association name.
|
1353
1353
|
|
1354
|
-
h6. +:source_type+
|
1354
|
+
h6(#has_many-source_type). +:source_type+
|
1355
1355
|
|
1356
1356
|
The +:source_type+ option specifies the source association type for a +has_many :through+ association that proceeds through a polymorphic association.
|
1357
1357
|
|
1358
|
-
h6. +:through+
|
1358
|
+
h6(#has_many-through). +:through+
|
1359
1359
|
|
1360
1360
|
The +:through+ option specifies a join model through which to perform the query. +has_many :through+ associations provide a way to implement many-to-many relationships, as discussed <a href="#the-has-many-through-association">earlier in this guide</a>.
|
1361
1361
|
|
1362
|
-
h6. +:uniq+
|
1362
|
+
h6(#has_many-uniq). +:uniq+
|
1363
1363
|
|
1364
1364
|
Specify the +:uniq => true+ option to remove duplicates from the collection. This is most useful in conjunction with the +:through+ option.
|
1365
1365
|
|
1366
|
-
h6. +:validate+
|
1366
|
+
h6(#has_many-validate). +:validate+
|
1367
1367
|
|
1368
1368
|
If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
|
1369
1369
|
|
1370
|
-
h5. When are Objects Saved?
|
1370
|
+
h5(#has_many-when_are_objects_saved). When are Objects Saved?
|
1371
1371
|
|
1372
1372
|
When you assign an object to a +has_many+ association, that object is automatically saved (in order to update its foreign key). If you assign multiple objects in one statement, then they are all saved.
|
1373
1373
|
|
@@ -1381,7 +1381,7 @@ h4. +has_and_belongs_to_many+ Association Reference
|
|
1381
1381
|
|
1382
1382
|
The +has_and_belongs_to_many+ association creates a many-to-many relationship with another model. In database terms, this associates two classes via an intermediate join table that includes foreign keys referring to each of the classes.
|
1383
1383
|
|
1384
|
-
h5. Methods Added
|
1384
|
+
h5. Methods Added by +has_and_belongs_to_many+
|
1385
1385
|
|
1386
1386
|
When you declare a +has_and_belongs_to_many+ association, the declaring class automatically gains 13 methods related to the association:
|
1387
1387
|
|
@@ -1478,7 +1478,7 @@ h6. <tt><em>collection</em>.clear</tt>
|
|
1478
1478
|
|
1479
1479
|
The <tt><em>collection</em>.clear</tt> method removes every object from the collection by deleting the rows from the joining table. This does not destroy the associated objects.
|
1480
1480
|
|
1481
|
-
h6. <tt><em>collection</em>.empty?</tt>
|
1481
|
+
h6(#has_and_belongs_to_many-collection-empty). <tt><em>collection</em>.empty?</tt>
|
1482
1482
|
|
1483
1483
|
The <tt><em>collection</em>.empty?</tt> method returns +true+ if the collection does not contain any associated objects.
|
1484
1484
|
|
@@ -1488,7 +1488,7 @@ The <tt><em>collection</em>.empty?</tt> method returns +true+ if the collection
|
|
1488
1488
|
<% end %>
|
1489
1489
|
</ruby>
|
1490
1490
|
|
1491
|
-
h6. <tt><em>collection</em>.size</tt>
|
1491
|
+
h6(#has_and_belongs_to_many-collection-size). <tt><em>collection</em>.size</tt>
|
1492
1492
|
|
1493
1493
|
The <tt><em>collection</em>.size</tt> method returns the number of objects in the collection.
|
1494
1494
|
|
@@ -1496,7 +1496,7 @@ The <tt><em>collection</em>.size</tt> method returns the number of objects in th
|
|
1496
1496
|
@assembly_count = @part.assemblies.size
|
1497
1497
|
</ruby>
|
1498
1498
|
|
1499
|
-
h6. <tt><em>collection</em>.find(...)</tt>
|
1499
|
+
h6(#has_and_belongs_to_many-collection-find). <tt><em>collection</em>.find(...)</tt>
|
1500
1500
|
|
1501
1501
|
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+. It also adds the additional condition that the object must be in the collection.
|
1502
1502
|
|
@@ -1505,7 +1505,7 @@ The <tt><em>collection</em>.find</tt> method finds objects within the collection
|
|
1505
1505
|
:conditions => ["created_at > ?", 2.days.ago])
|
1506
1506
|
</ruby>
|
1507
1507
|
|
1508
|
-
h6. <tt><em>collection</em>.exists?(...)</tt>
|
1508
|
+
h6(#has_and_belongs_to_many-collection-exists). <tt><em>collection</em>.exists?(...)</tt>
|
1509
1509
|
|
1510
1510
|
The <tt><em>collection</em>.exists?</tt> method checks whether an object meeting the supplied conditions exists in the collection. It uses the same syntax and options as +ActiveRecord::Base.exists?+.
|
1511
1511
|
|
@@ -1518,7 +1518,7 @@ The <tt><em>collection</em>.build</tt> method returns a new object of the associ
|
|
1518
1518
|
{:assembly_name => "Transmission housing"})
|
1519
1519
|
</ruby>
|
1520
1520
|
|
1521
|
-
h6. <tt><em>collection</em>.create(attributes = {})</tt>
|
1521
|
+
h6(#has_and_belongs_to_many-create-attributes). <tt><em>collection</em>.create(attributes = {})</tt>
|
1522
1522
|
|
1523
1523
|
The <tt><em>collection</em>.create</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through the join table will be created, and the associated object _will_ be saved (assuming that it passes any validations).
|
1524
1524
|
|
@@ -1575,11 +1575,11 @@ class User < ActiveRecord::Base
|
|
1575
1575
|
end
|
1576
1576
|
</ruby>
|
1577
1577
|
|
1578
|
-
h6. +:autosave+
|
1578
|
+
h6(#has_and_belongs_to_many-autosave). +:autosave+
|
1579
1579
|
|
1580
1580
|
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
|
1581
1581
|
|
1582
|
-
h6. +:class_name+
|
1582
|
+
h6(#has_and_belongs_to_many-class_name). +:class_name+
|
1583
1583
|
|
1584
1584
|
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if a part has many assemblies, but the actual name of the model containing assemblies is +Gadget+, you'd set things up this way:
|
1585
1585
|
|
@@ -1589,7 +1589,7 @@ class Parts < ActiveRecord::Base
|
|
1589
1589
|
end
|
1590
1590
|
</ruby>
|
1591
1591
|
|
1592
|
-
h6. +:conditions+
|
1592
|
+
h6(#has_and_belongs_to_many-conditions). +:conditions+
|
1593
1593
|
|
1594
1594
|
The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL +WHERE+ clause).
|
1595
1595
|
|
@@ -1611,7 +1611,7 @@ end
|
|
1611
1611
|
|
1612
1612
|
If you use a hash-style +:conditions+ option, then record creation via this association will be automatically scoped using the hash. In this case, using +@parts.assemblies.create+ or +@parts.assemblies.build+ will create orders where the +factory+ column has the value "Seattle".
|
1613
1613
|
|
1614
|
-
h6. +:counter_sql+
|
1614
|
+
h6(#has_and_belongs_to_many-counter_sql). +:counter_sql+
|
1615
1615
|
|
1616
1616
|
Normally Rails automatically generates the proper SQL to count the association members. With the +:counter_sql+ option, you can specify a complete SQL statement to count them yourself.
|
1617
1617
|
|
@@ -1621,15 +1621,15 @@ h6. +:delete_sql+
|
|
1621
1621
|
|
1622
1622
|
Normally Rails automatically generates the proper SQL to remove links between the associated classes. With the +:delete_sql+ option, you can specify a complete SQL statement to delete them yourself.
|
1623
1623
|
|
1624
|
-
h6. +:extend+
|
1624
|
+
h6(#has_and_belongs_to_many-extend). +:extend+
|
1625
1625
|
|
1626
1626
|
The +:extend+ option specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
|
1627
1627
|
|
1628
|
-
h6. +:finder_sql+
|
1628
|
+
h6(#has_and_belongs_to_many-finder_sql). +:finder_sql+
|
1629
1629
|
|
1630
1630
|
Normally Rails automatically generates the proper SQL to fetch the association members. With the +:finder_sql+ option, you can specify a complete SQL statement to fetch them yourself. If fetching objects requires complex multi-table SQL, this may be necessary.
|
1631
1631
|
|
1632
|
-
h6. +:foreign_key+
|
1632
|
+
h6(#has_and_belongs_to_many-foreign_key). +:foreign_key+
|
1633
1633
|
|
1634
1634
|
By convention, Rails guesses that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
|
1635
1635
|
|
@@ -1641,7 +1641,7 @@ class User < ActiveRecord::Base
|
|
1641
1641
|
end
|
1642
1642
|
</ruby>
|
1643
1643
|
|
1644
|
-
h6. +:group+
|
1644
|
+
h6(#has_and_belongs_to_many-group). +:group+
|
1645
1645
|
|
1646
1646
|
The +:group+ option supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
|
1647
1647
|
|
@@ -1651,7 +1651,7 @@ class Parts < ActiveRecord::Base
|
|
1651
1651
|
end
|
1652
1652
|
</ruby>
|
1653
1653
|
|
1654
|
-
h6. +:include+
|
1654
|
+
h6(#has_and_belongs_to_many-include). +:include+
|
1655
1655
|
|
1656
1656
|
You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used.
|
1657
1657
|
|
@@ -1663,7 +1663,7 @@ h6. +:join_table+
|
|
1663
1663
|
|
1664
1664
|
If the default name of the join table, based on lexical ordering, is not what you want, you can use the +:join_table+ option to override the default.
|
1665
1665
|
|
1666
|
-
h6. +:limit+
|
1666
|
+
h6(#has_and_belongs_to_many-limit). +:limit+
|
1667
1667
|
|
1668
1668
|
The +:limit+ option lets you restrict the total number of objects that will be fetched through an association.
|
1669
1669
|
|
@@ -1674,11 +1674,11 @@ class Parts < ActiveRecord::Base
|
|
1674
1674
|
end
|
1675
1675
|
</ruby>
|
1676
1676
|
|
1677
|
-
h6. +:offset+
|
1677
|
+
h6(#has_and_belongs_to_many-offset). +:offset+
|
1678
1678
|
|
1679
1679
|
The +:offset+ option lets you specify the starting offset for fetching objects via an association. For example, if you set +:offset => 11+, it will skip the first 11 records.
|
1680
1680
|
|
1681
|
-
h6. +:order+
|
1681
|
+
h6(#has_and_belongs_to_many-order). +:order+
|
1682
1682
|
|
1683
1683
|
The +:order+ option dictates the order in which associated objects will be received (in the syntax used by a SQL +ORDER BY+ clause).
|
1684
1684
|
|
@@ -1688,23 +1688,23 @@ class Parts < ActiveRecord::Base
|
|
1688
1688
|
end
|
1689
1689
|
</ruby>
|
1690
1690
|
|
1691
|
-
h6. +:readonly+
|
1691
|
+
h6(#has_and_belongs_to_many-readonly). +:readonly+
|
1692
1692
|
|
1693
1693
|
If you set the +:readonly+ option to +true+, then the associated objects will be read-only when retrieved via the association.
|
1694
1694
|
|
1695
|
-
h6. +:select+
|
1695
|
+
h6(#has_and_belongs_to_many-select). +:select+
|
1696
1696
|
|
1697
1697
|
The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
|
1698
1698
|
|
1699
|
-
h6. +:uniq+
|
1699
|
+
h6(#has_and_belongs_to_many-uniq). +:uniq+
|
1700
1700
|
|
1701
1701
|
Specify the +:uniq => true+ option to remove duplicates from the collection.
|
1702
1702
|
|
1703
|
-
h6. +:validate+
|
1703
|
+
h6(#has_and_belongs_to_many-validate). +:validate+
|
1704
1704
|
|
1705
1705
|
If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
|
1706
1706
|
|
1707
|
-
h5. When are Objects Saved?
|
1707
|
+
h5(#has_and_belongs_to_many-when_are_objects_saved). When are Objects Saved?
|
1708
1708
|
|
1709
1709
|
When you assign an object to a +has_and_belongs_to_many+ association, that object is automatically saved (in order to update the join table). If you assign multiple objects in one statement, then they are all saved.
|
1710
1710
|
|
@@ -1809,6 +1809,7 @@ h3. Changelog
|
|
1809
1809
|
|
1810
1810
|
"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/11
|
1811
1811
|
|
1812
|
+
* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
|
1812
1813
|
* April 19, 2009: Added +:touch+ option to +belongs_to+ associations by "Mike Gunderloy":credits.html#mgunderloy
|
1813
1814
|
* February 1, 2009: Added +:autosave+ option "Mike Gunderloy":credits.html#mgunderloy
|
1814
1815
|
* September 28, 2008: Corrected +has_many :through+ diagram, added polymorphic diagram, some reorganization by "Mike Gunderloy":credits.html#mgunderloy . First release version.
|