rails 4.0.0 → 4.2.11.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +30 -23
- data/guides/CHANGELOG.md +108 -6
- data/guides/Rakefile +21 -6
- data/guides/assets/images/akshaysurve.jpg +0 -0
- data/guides/assets/images/edge_badge.png +0 -0
- data/guides/assets/images/feature_tile.gif +0 -0
- data/guides/assets/images/footer_tile.gif +0 -0
- data/guides/assets/images/fxn.png +0 -0
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/images/getting_started/challenge.png +0 -0
- data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
- data/guides/assets/images/getting_started/form_with_errors.png +0 -0
- data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
- data/guides/assets/images/getting_started/new_article.png +0 -0
- data/guides/assets/images/getting_started/rails_welcome.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
- data/guides/assets/images/header_tile.gif +0 -0
- data/guides/assets/images/icons/README +1 -1
- data/guides/assets/images/icons/callouts/11.png +0 -0
- data/guides/assets/images/icons/callouts/12.png +0 -0
- data/guides/assets/images/icons/callouts/13.png +0 -0
- data/guides/assets/images/icons/callouts/15.png +0 -0
- data/guides/assets/images/icons/caution.png +0 -0
- data/guides/assets/images/icons/example.png +0 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/rails4_features.png +0 -0
- data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/assets/javascripts/guides.js +36 -34
- data/guides/assets/stylesheets/main.css +6 -2
- data/guides/assets/stylesheets/print.css +1 -1
- data/guides/bug_report_templates/action_controller_gem.rb +47 -0
- data/guides/bug_report_templates/action_controller_master.rb +54 -0
- data/guides/bug_report_templates/active_record_gem.rb +5 -2
- data/guides/bug_report_templates/active_record_master.rb +3 -2
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/rails_guides.rb +23 -4
- data/guides/rails_guides/generator.rb +1 -1
- data/guides/rails_guides/helpers.rb +4 -2
- data/guides/rails_guides/levenshtein.rb +27 -21
- data/guides/rails_guides/markdown.rb +11 -7
- data/guides/rails_guides/markdown/renderer.rb +1 -1
- data/guides/source/2_2_release_notes.md +3 -3
- data/guides/source/2_3_release_notes.md +12 -12
- data/guides/source/3_0_release_notes.md +10 -13
- data/guides/source/3_1_release_notes.md +7 -4
- data/guides/source/3_2_release_notes.md +17 -14
- data/guides/source/4_0_release_notes.md +110 -54
- data/guides/source/4_1_release_notes.md +730 -0
- data/guides/source/4_2_release_notes.md +877 -0
- data/guides/source/_license.html.erb +1 -1
- data/guides/source/_welcome.html.erb +6 -2
- data/guides/source/action_controller_overview.md +223 -57
- data/guides/source/action_mailer_basics.md +129 -76
- data/guides/source/action_view_overview.md +247 -246
- data/guides/source/active_job_basics.md +339 -0
- data/guides/source/active_model_basics.md +374 -20
- data/guides/source/active_record_basics.md +46 -45
- data/guides/source/active_record_callbacks.md +83 -28
- data/guides/source/{migrations.md → active_record_migrations.md} +191 -275
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +382 -300
- data/guides/source/active_record_validations.md +64 -55
- data/guides/source/active_support_core_extensions.md +229 -187
- data/guides/source/active_support_instrumentation.md +23 -22
- data/guides/source/api_documentation_guidelines.md +167 -15
- data/guides/source/asset_pipeline.md +768 -294
- data/guides/source/association_basics.md +188 -96
- data/guides/source/autoloading_and_reloading_constants.md +1311 -0
- data/guides/source/caching_with_rails.md +45 -11
- data/guides/source/command_line.md +96 -65
- data/guides/source/configuring.md +404 -70
- data/guides/source/contributing_to_ruby_on_rails.md +270 -130
- data/guides/source/credits.html.erb +7 -3
- data/guides/source/debugging_rails_applications.md +471 -284
- data/guides/source/development_dependencies_install.md +115 -21
- data/guides/source/documents.yaml +31 -9
- data/guides/source/engines.md +737 -291
- data/guides/source/form_helpers.md +137 -89
- data/guides/source/generators.md +60 -28
- data/guides/source/getting_started.md +1007 -596
- data/guides/source/i18n.md +178 -96
- data/guides/source/index.html.erb +2 -1
- data/guides/source/initialization.md +248 -104
- data/guides/source/kindle/toc.html.erb +1 -1
- data/guides/source/layout.html.erb +14 -22
- data/guides/source/layouts_and_rendering.md +78 -46
- data/guides/source/maintenance_policy.md +78 -0
- data/guides/source/nested_model_forms.md +10 -7
- data/guides/source/plugins.md +66 -57
- data/guides/source/rails_application_templates.md +49 -12
- data/guides/source/rails_on_rack.md +50 -60
- data/guides/source/routing.md +190 -139
- data/guides/source/ruby_on_rails_guides_guidelines.md +12 -13
- data/guides/source/security.md +134 -83
- data/guides/source/testing.md +322 -200
- data/guides/source/upgrading_ruby_on_rails.md +834 -37
- data/guides/source/working_with_javascript_in_rails.md +36 -26
- data/guides/w3c_validator.rb +2 -0
- metadata +93 -116
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
- data/guides/assets/images/getting_started/new_post.png +0 -0
- data/guides/assets/images/getting_started/post_with_comments.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_posts.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
- data/guides/assets/images/getting_started/undefined_method_post_path.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
- data/guides/assets/images/jaimeiniesta.jpg +0 -0
- data/guides/code/getting_started/Gemfile +0 -43
- data/guides/code/getting_started/Gemfile.lock +0 -150
- data/guides/code/getting_started/README.rdoc +0 -28
- data/guides/code/getting_started/Rakefile +0 -6
- data/guides/code/getting_started/app/assets/javascripts/application.js +0 -16
- data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
- data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
- data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
- data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -17
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -47
- data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
- data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
- data/guides/code/getting_started/app/models/comment.rb +0 -3
- data/guides/code/getting_started/app/models/post.rb +0 -7
- data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
- data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
- data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
- data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
- data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
- data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
- data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -3
- data/guides/code/getting_started/bin/bundle +0 -4
- data/guides/code/getting_started/bin/rails +0 -4
- data/guides/code/getting_started/bin/rake +0 -4
- data/guides/code/getting_started/config.ru +0 -4
- data/guides/code/getting_started/config/application.rb +0 -18
- data/guides/code/getting_started/config/boot.rb +0 -4
- data/guides/code/getting_started/config/database.yml +0 -25
- data/guides/code/getting_started/config/environment.rb +0 -5
- data/guides/code/getting_started/config/environments/development.rb +0 -30
- data/guides/code/getting_started/config/environments/production.rb +0 -80
- data/guides/code/getting_started/config/environments/test.rb +0 -36
- data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
- data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
- data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
- data/guides/code/getting_started/config/initializers/locale.rb +0 -9
- data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
- data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
- data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
- data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
- data/guides/code/getting_started/config/locales/en.yml +0 -23
- data/guides/code/getting_started/config/routes.rb +0 -7
- data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
- data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
- data/guides/code/getting_started/db/schema.rb +0 -33
- data/guides/code/getting_started/db/seeds.rb +0 -7
- data/guides/code/getting_started/public/404.html +0 -58
- data/guides/code/getting_started/public/422.html +0 -58
- data/guides/code/getting_started/public/500.html +0 -57
- data/guides/code/getting_started/public/favicon.ico +0 -0
- data/guides/code/getting_started/public/robots.txt +0 -5
- data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
- data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
- data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
- data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
- data/guides/code/getting_started/test/models/comment_test.rb +0 -7
- data/guides/code/getting_started/test/models/post_test.rb +0 -7
- data/guides/code/getting_started/test/test_helper.rb +0 -15
- data/guides/source/kindle/KINDLE.md +0 -26
@@ -1,4 +1,4 @@
|
|
1
|
-
Rails
|
1
|
+
Rails Nested Model Forms
|
2
2
|
========================
|
3
3
|
|
4
4
|
Creating a form for a model _and_ its associations can become quite tedious. Therefore Rails provides helpers to assist in dealing with the complexities of generating these forms _and_ the required CRUD operations to create, update, and destroy associations.
|
@@ -9,7 +9,7 @@ After reading this guide, you will know:
|
|
9
9
|
|
10
10
|
--------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
NOTE: This guide assumes the user knows how to use the [Rails form helpers](form_helpers.html) in general. Also, it
|
12
|
+
NOTE: This guide assumes the user knows how to use the [Rails form helpers](form_helpers.html) in general. Also, it's **not** an API reference. For a complete reference please visit [the Rails API documentation](http://api.rubyonrails.org/).
|
13
13
|
|
14
14
|
|
15
15
|
Model setup
|
@@ -17,9 +17,9 @@ Model setup
|
|
17
17
|
|
18
18
|
To be able to use the nested model functionality in your forms, the model will need to support some basic operations.
|
19
19
|
|
20
|
-
First of all, it needs to define a writer method for the attribute that corresponds to the association you are building a nested model form for. The `fields_for` form helper will look for this method to decide whether or not a nested model form should be
|
20
|
+
First of all, it needs to define a writer method for the attribute that corresponds to the association you are building a nested model form for. The `fields_for` form helper will look for this method to decide whether or not a nested model form should be built.
|
21
21
|
|
22
|
-
If the associated object is an array a form builder will be yielded for each object, else only a single form builder will be yielded.
|
22
|
+
If the associated object is an array, a form builder will be yielded for each object, else only a single form builder will be yielded.
|
23
23
|
|
24
24
|
Consider a Person model with an associated Address. When asked to yield a nested FormBuilder for the `:address` attribute, the `fields_for` form helper will look for a method on the Person instance named `address_attributes=`.
|
25
25
|
|
@@ -54,9 +54,12 @@ class Person < ActiveRecord::Base
|
|
54
54
|
end
|
55
55
|
```
|
56
56
|
|
57
|
+
NOTE: For greater detail on associations see [Active Record Associations](association_basics.html).
|
58
|
+
For a complete reference on associations please visit the API documentation for [ActiveRecord::Associations::ClassMethods](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html).
|
59
|
+
|
57
60
|
### Custom model
|
58
61
|
|
59
|
-
As you might have inflected from this explanation, you _don
|
62
|
+
As you might have inflected from this explanation, you _don't_ necessarily need an ActiveRecord::Base model to use this functionality. The following examples are sufficient to enable the nested model form behavior:
|
60
63
|
|
61
64
|
#### Single associated object
|
62
65
|
|
@@ -177,7 +180,7 @@ When this form is posted the Rails parameter parser will construct a hash like t
|
|
177
180
|
}
|
178
181
|
```
|
179
182
|
|
180
|
-
That
|
183
|
+
That's it. The controller will simply pass this hash on to the model from the `create` action. The model will then handle building the `address` association for you and automatically save it when the parent (`person`) is saved.
|
181
184
|
|
182
185
|
#### Nested form for a collection of associated objects
|
183
186
|
|
@@ -220,6 +223,6 @@ As you can see it has generated 2 `project name` inputs, one for each new `proje
|
|
220
223
|
|
221
224
|
You can basically see the `projects_attributes` hash as an array of attribute hashes, one for each model instance.
|
222
225
|
|
223
|
-
NOTE: The reason that `fields_for` constructed a
|
226
|
+
NOTE: The reason that `fields_for` constructed a hash instead of an array is that it won't work for any form nested deeper than one level deep.
|
224
227
|
|
225
228
|
TIP: You _can_ however pass an array to the writer method generated by `accepts_nested_attributes_for` if you're using plain Ruby or some other API access. See (TODO) for more info and example.
|
data/guides/source/plugins.md
CHANGED
@@ -3,9 +3,9 @@ The Basics of Creating Rails Plugins
|
|
3
3
|
|
4
4
|
A Rails plugin is either an extension or a modification of the core framework. Plugins provide:
|
5
5
|
|
6
|
-
*
|
7
|
-
*
|
8
|
-
*
|
6
|
+
* A way for developers to share bleeding-edge ideas without hurting the stable code base.
|
7
|
+
* A segmented architecture so that units of code can be fixed or updated on their own release schedule.
|
8
|
+
* An outlet for the core developers so that they don't have to include every cool new feature under the sun.
|
9
9
|
|
10
10
|
After reading this guide, you will know:
|
11
11
|
|
@@ -15,7 +15,7 @@ After reading this guide, you will know:
|
|
15
15
|
This guide describes how to build a test-driven plugin that will:
|
16
16
|
|
17
17
|
* Extend core Ruby classes like Hash and String.
|
18
|
-
* Add methods to ActiveRecord::Base in the tradition of the
|
18
|
+
* Add methods to `ActiveRecord::Base` in the tradition of the `acts_as` plugins.
|
19
19
|
* Give you information about where to put generators in your plugin.
|
20
20
|
|
21
21
|
For the purpose of this guide pretend for a moment that you are an avid bird watcher.
|
@@ -34,15 +34,21 @@ different rails applications using RubyGems and Bundler if desired.
|
|
34
34
|
|
35
35
|
|
36
36
|
Rails ships with a `rails plugin new` command which creates a
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
skeleton for developing any kind of Rails extension with the ability
|
38
|
+
to run integration tests using a dummy Rails application. Create your
|
39
|
+
plugin with the command:
|
40
40
|
|
41
41
|
```bash
|
42
|
-
$ rails plugin
|
42
|
+
$ rails plugin new yaffle
|
43
43
|
```
|
44
44
|
|
45
|
-
|
45
|
+
See usage and options by asking for help:
|
46
|
+
|
47
|
+
```bash
|
48
|
+
$ rails plugin new --help
|
49
|
+
```
|
50
|
+
|
51
|
+
Testing Your Newly Generated Plugin
|
46
52
|
-----------------------------------
|
47
53
|
|
48
54
|
You can navigate to the directory that contains the plugin, run the `bundle install` command
|
@@ -51,7 +57,7 @@ You can navigate to the directory that contains the plugin, run the `bundle inst
|
|
51
57
|
You should see:
|
52
58
|
|
53
59
|
```bash
|
54
|
-
|
60
|
+
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
|
55
61
|
```
|
56
62
|
|
57
63
|
This will tell you that everything got generated properly and you are ready to start adding functionality.
|
@@ -68,7 +74,7 @@ In this example you will add a method to String named `to_squawk`. To begin, cre
|
|
68
74
|
|
69
75
|
require 'test_helper'
|
70
76
|
|
71
|
-
class CoreExtTest <
|
77
|
+
class CoreExtTest < ActiveSupport::TestCase
|
72
78
|
def test_to_squawk_prepends_the_word_squawk
|
73
79
|
assert_equal "squawk! Hello World", "Hello World".to_squawk
|
74
80
|
end
|
@@ -79,19 +85,19 @@ Run `rake` to run the test. This test should fail because we haven't implemented
|
|
79
85
|
|
80
86
|
```bash
|
81
87
|
1) Error:
|
82
|
-
test_to_squawk_prepends_the_word_squawk
|
83
|
-
NoMethodError: undefined method `to_squawk' for
|
84
|
-
|
88
|
+
CoreExtTest#test_to_squawk_prepends_the_word_squawk:
|
89
|
+
NoMethodError: undefined method `to_squawk' for "Hello World":String
|
90
|
+
/path/to/yaffle/test/core_ext_test.rb:5:in `test_to_squawk_prepends_the_word_squawk'
|
85
91
|
```
|
86
92
|
|
87
93
|
Great - now you are ready to start development.
|
88
94
|
|
89
|
-
|
95
|
+
In `lib/yaffle.rb`, add `require 'yaffle/core_ext'`:
|
90
96
|
|
91
97
|
```ruby
|
92
98
|
# yaffle/lib/yaffle.rb
|
93
99
|
|
94
|
-
require
|
100
|
+
require 'yaffle/core_ext'
|
95
101
|
|
96
102
|
module Yaffle
|
97
103
|
end
|
@@ -112,13 +118,13 @@ end
|
|
112
118
|
To test that your method does what it says it does, run the unit tests with `rake` from your plugin directory.
|
113
119
|
|
114
120
|
```bash
|
115
|
-
|
121
|
+
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
|
116
122
|
```
|
117
123
|
|
118
124
|
To see this in action, change to the test/dummy directory, fire up a console and start squawking:
|
119
125
|
|
120
126
|
```bash
|
121
|
-
$ rails console
|
127
|
+
$ bin/rails console
|
122
128
|
>> "Hello World".to_squawk
|
123
129
|
=> "squawk! Hello World"
|
124
130
|
```
|
@@ -126,8 +132,8 @@ $ rails console
|
|
126
132
|
Add an "acts_as" Method to Active Record
|
127
133
|
----------------------------------------
|
128
134
|
|
129
|
-
A common pattern in plugins is to add a method called
|
130
|
-
want to write a method called
|
135
|
+
A common pattern in plugins is to add a method called `acts_as_something` to models. In this case, you
|
136
|
+
want to write a method called `acts_as_yaffle` that adds a `squawk` method to your Active Record models.
|
131
137
|
|
132
138
|
To begin, set up your files so that you have:
|
133
139
|
|
@@ -136,14 +142,14 @@ To begin, set up your files so that you have:
|
|
136
142
|
|
137
143
|
require 'test_helper'
|
138
144
|
|
139
|
-
class ActsAsYaffleTest <
|
145
|
+
class ActsAsYaffleTest < ActiveSupport::TestCase
|
140
146
|
end
|
141
147
|
```
|
142
148
|
|
143
149
|
```ruby
|
144
150
|
# yaffle/lib/yaffle.rb
|
145
151
|
|
146
|
-
require
|
152
|
+
require 'yaffle/core_ext'
|
147
153
|
require 'yaffle/acts_as_yaffle'
|
148
154
|
|
149
155
|
module Yaffle
|
@@ -162,9 +168,9 @@ end
|
|
162
168
|
|
163
169
|
### Add a Class Method
|
164
170
|
|
165
|
-
This plugin will expect that you've added a method to your model named
|
166
|
-
plugin users might have already defined a method on their model named
|
167
|
-
for something else. This plugin will allow the name to be changed by adding a class method called
|
171
|
+
This plugin will expect that you've added a method to your model named `last_squawk`. However, the
|
172
|
+
plugin users might have already defined a method on their model named `last_squawk` that they use
|
173
|
+
for something else. This plugin will allow the name to be changed by adding a class method called `yaffle_text_field`.
|
168
174
|
|
169
175
|
To start out, write a failing test that shows the behavior you'd like:
|
170
176
|
|
@@ -173,7 +179,7 @@ To start out, write a failing test that shows the behavior you'd like:
|
|
173
179
|
|
174
180
|
require 'test_helper'
|
175
181
|
|
176
|
-
class ActsAsYaffleTest <
|
182
|
+
class ActsAsYaffleTest < ActiveSupport::TestCase
|
177
183
|
|
178
184
|
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
|
179
185
|
assert_equal "last_squawk", Hickwall.yaffle_text_field
|
@@ -190,16 +196,16 @@ When you run `rake`, you should see the following:
|
|
190
196
|
|
191
197
|
```
|
192
198
|
1) Error:
|
193
|
-
test_a_hickwalls_yaffle_text_field_should_be_last_squawk
|
199
|
+
ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
|
194
200
|
NameError: uninitialized constant ActsAsYaffleTest::Hickwall
|
195
|
-
|
201
|
+
/path/to/yaffle/test/acts_as_yaffle_test.rb:6:in `test_a_hickwalls_yaffle_text_field_should_be_last_squawk'
|
196
202
|
|
197
203
|
2) Error:
|
198
|
-
test_a_wickwalls_yaffle_text_field_should_be_last_tweet
|
204
|
+
ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
|
199
205
|
NameError: uninitialized constant ActsAsYaffleTest::Wickwall
|
200
|
-
|
206
|
+
/path/to/yaffle/test/acts_as_yaffle_test.rb:10:in `test_a_wickwalls_yaffle_text_field_should_be_last_tweet'
|
201
207
|
|
202
|
-
|
208
|
+
4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
|
203
209
|
```
|
204
210
|
|
205
211
|
This tells us that we don't have the necessary models (Hickwall and Wickwall) that we are trying to test.
|
@@ -208,17 +214,16 @@ test/dummy directory:
|
|
208
214
|
|
209
215
|
```bash
|
210
216
|
$ cd test/dummy
|
211
|
-
$ rails generate model Hickwall last_squawk:string
|
212
|
-
$ rails generate model Wickwall last_squawk:string last_tweet:string
|
217
|
+
$ bin/rails generate model Hickwall last_squawk:string
|
218
|
+
$ bin/rails generate model Wickwall last_squawk:string last_tweet:string
|
213
219
|
```
|
214
220
|
|
215
221
|
Now you can create the necessary database tables in your testing database by navigating to your dummy app
|
216
|
-
and migrating the database. First
|
222
|
+
and migrating the database. First, run:
|
217
223
|
|
218
224
|
```bash
|
219
225
|
$ cd test/dummy
|
220
|
-
$ rake db:migrate
|
221
|
-
$ rake db:test:prepare
|
226
|
+
$ bin/rake db:migrate
|
222
227
|
```
|
223
228
|
|
224
229
|
While you are here, change the Hickwall and Wickwall models so that they know that they are supposed to act
|
@@ -239,7 +244,7 @@ end
|
|
239
244
|
|
240
245
|
```
|
241
246
|
|
242
|
-
We will also add code to define the acts_as_yaffle method.
|
247
|
+
We will also add code to define the `acts_as_yaffle` method.
|
243
248
|
|
244
249
|
```ruby
|
245
250
|
# yaffle/lib/yaffle/acts_as_yaffle.rb
|
@@ -265,22 +270,22 @@ You can then return to the root directory (`cd ../..`) of your plugin and rerun
|
|
265
270
|
|
266
271
|
```
|
267
272
|
1) Error:
|
268
|
-
test_a_hickwalls_yaffle_text_field_should_be_last_squawk
|
269
|
-
NoMethodError: undefined method `yaffle_text_field' for #<Class:
|
270
|
-
|
271
|
-
|
273
|
+
ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
|
274
|
+
NoMethodError: undefined method `yaffle_text_field' for #<Class:0x007fd105e3b218>
|
275
|
+
activerecord (4.1.5) lib/active_record/dynamic_matchers.rb:26:in `method_missing'
|
276
|
+
/path/to/yaffle/test/acts_as_yaffle_test.rb:6:in `test_a_hickwalls_yaffle_text_field_should_be_last_squawk'
|
272
277
|
|
273
278
|
2) Error:
|
274
|
-
test_a_wickwalls_yaffle_text_field_should_be_last_tweet
|
275
|
-
NoMethodError: undefined method `yaffle_text_field' for #<Class:
|
276
|
-
|
277
|
-
|
279
|
+
ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
|
280
|
+
NoMethodError: undefined method `yaffle_text_field' for #<Class:0x007fd105e409c0>
|
281
|
+
activerecord (4.1.5) lib/active_record/dynamic_matchers.rb:26:in `method_missing'
|
282
|
+
/path/to/yaffle/test/acts_as_yaffle_test.rb:10:in `test_a_wickwalls_yaffle_text_field_should_be_last_tweet'
|
278
283
|
|
279
|
-
|
284
|
+
4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
|
280
285
|
|
281
286
|
```
|
282
287
|
|
283
|
-
Getting closer... Now we will implement the code of the acts_as_yaffle method to make the tests pass.
|
288
|
+
Getting closer... Now we will implement the code of the `acts_as_yaffle` method to make the tests pass.
|
284
289
|
|
285
290
|
```ruby
|
286
291
|
# yaffle/lib/yaffle/acts_as_yaffle.rb
|
@@ -304,10 +309,10 @@ end
|
|
304
309
|
ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle
|
305
310
|
```
|
306
311
|
|
307
|
-
When you run `rake
|
312
|
+
When you run `rake`, you should see the tests all pass:
|
308
313
|
|
309
314
|
```bash
|
310
|
-
|
315
|
+
4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
|
311
316
|
```
|
312
317
|
|
313
318
|
### Add an Instance Method
|
@@ -321,7 +326,7 @@ To start out, write a failing test that shows the behavior you'd like:
|
|
321
326
|
# yaffle/test/acts_as_yaffle_test.rb
|
322
327
|
require 'test_helper'
|
323
328
|
|
324
|
-
class ActsAsYaffleTest <
|
329
|
+
class ActsAsYaffleTest < ActiveSupport::TestCase
|
325
330
|
|
326
331
|
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
|
327
332
|
assert_equal "last_squawk", Hickwall.yaffle_text_field
|
@@ -381,10 +386,14 @@ ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle
|
|
381
386
|
Run `rake` one final time and you should see:
|
382
387
|
|
383
388
|
```
|
384
|
-
|
389
|
+
6 runs, 6 assertions, 0 failures, 0 errors, 0 skips
|
385
390
|
```
|
386
391
|
|
387
|
-
NOTE: The use of `write_attribute` to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use
|
392
|
+
NOTE: The use of `write_attribute` to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use:
|
393
|
+
|
394
|
+
```ruby
|
395
|
+
send("#{self.class.yaffle_text_field}=", string.to_squawk)
|
396
|
+
```
|
388
397
|
|
389
398
|
Generators
|
390
399
|
----------
|
@@ -392,7 +401,7 @@ Generators
|
|
392
401
|
Generators can be included in your gem simply by creating them in a lib/generators directory of your plugin. More information about
|
393
402
|
the creation of generators can be found in the [Generators Guide](generators.html)
|
394
403
|
|
395
|
-
Publishing
|
404
|
+
Publishing Your Gem
|
396
405
|
-------------------
|
397
406
|
|
398
407
|
Gem plugins currently in development can easily be shared from any Git repository. To share the Yaffle gem with others, simply
|
@@ -405,12 +414,12 @@ gem 'yaffle', git: 'git://github.com/yaffle_watcher/yaffle.git'
|
|
405
414
|
After running `bundle install`, your gem functionality will be available to the application.
|
406
415
|
|
407
416
|
When the gem is ready to be shared as a formal release, it can be published to [RubyGems](http://www.rubygems.org).
|
408
|
-
For more information about publishing gems to RubyGems, see: [Creating and Publishing Your First Ruby Gem](http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html)
|
417
|
+
For more information about publishing gems to RubyGems, see: [Creating and Publishing Your First Ruby Gem](http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html).
|
409
418
|
|
410
419
|
RDoc Documentation
|
411
420
|
------------------
|
412
421
|
|
413
|
-
Once your plugin is stable and you are ready to deploy do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy.
|
422
|
+
Once your plugin is stable and you are ready to deploy, do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy.
|
414
423
|
|
415
424
|
The first step is to update the README file with detailed information about how to use your plugin. A few key things to include are:
|
416
425
|
|
@@ -424,12 +433,12 @@ Once your README is solid, go through and add rdoc comments to all of the method
|
|
424
433
|
Once your comments are good to go, navigate to your plugin directory and run:
|
425
434
|
|
426
435
|
```bash
|
427
|
-
$ rake rdoc
|
436
|
+
$ bin/rake rdoc
|
428
437
|
```
|
429
438
|
|
430
439
|
### References
|
431
440
|
|
432
441
|
* [Developing a RubyGem using Bundler](https://github.com/radar/guides/blob/master/gem-development.md)
|
433
442
|
* [Using .gemspecs as Intended](http://yehudakatz.com/2010/04/02/using-gemspecs-as-intended/)
|
434
|
-
* [Gemspec Reference](http://
|
443
|
+
* [Gemspec Reference](http://guides.rubygems.org/specification-reference/)
|
435
444
|
* [GemPlugins: A Brief Introduction to the Future of Rails Plugins](http://www.intridea.com/blog/2008/6/11/gemplugins-a-brief-introduction-to-the-future-of-rails-plugins)
|
@@ -23,8 +23,8 @@ $ rails new blog -m http://example.com/template.rb
|
|
23
23
|
You can use the rake task `rails:template` to apply templates to an existing Rails application. The location of the template needs to be passed in to an environment variable named LOCATION. Again, this can either be path to a file or a URL.
|
24
24
|
|
25
25
|
```bash
|
26
|
-
$ rake rails:template LOCATION=~/template.rb
|
27
|
-
$ rake rails:template LOCATION=http://example.com/template.rb
|
26
|
+
$ bin/rake rails:template LOCATION=~/template.rb
|
27
|
+
$ bin/rake rails:template LOCATION=http://example.com/template.rb
|
28
28
|
```
|
29
29
|
|
30
30
|
Template API
|
@@ -38,16 +38,18 @@ generate(:scaffold, "person name:string")
|
|
38
38
|
route "root to: 'people#index'"
|
39
39
|
rake("db:migrate")
|
40
40
|
|
41
|
-
|
42
|
-
git
|
43
|
-
git
|
41
|
+
after_bundle do
|
42
|
+
git :init
|
43
|
+
git add: "."
|
44
|
+
git commit: %Q{ -m 'Initial commit' }
|
45
|
+
end
|
44
46
|
```
|
45
47
|
|
46
48
|
The following sections outline the primary methods provided by the API:
|
47
49
|
|
48
50
|
### gem(*args)
|
49
51
|
|
50
|
-
Adds a `gem` entry for the supplied gem to the generated application
|
52
|
+
Adds a `gem` entry for the supplied gem to the generated application's `Gemfile`.
|
51
53
|
|
52
54
|
For example, if your application depends on the gems `bj` and `nokogiri`:
|
53
55
|
|
@@ -78,7 +80,7 @@ end
|
|
78
80
|
|
79
81
|
Adds the given source to the generated application's `Gemfile`.
|
80
82
|
|
81
|
-
For example, if you need to source a gem from "http://code.whytheluckystiff.net"
|
83
|
+
For example, if you need to source a gem from `"http://code.whytheluckystiff.net"`:
|
82
84
|
|
83
85
|
```ruby
|
84
86
|
add_source "http://code.whytheluckystiff.net"
|
@@ -91,14 +93,14 @@ Adds a line inside the `Application` class for `config/application.rb`.
|
|
91
93
|
If `options[:env]` is specified, the line is appended to the corresponding file in `config/environments`.
|
92
94
|
|
93
95
|
```ruby
|
94
|
-
environment 'config.action_mailer.default_url_options = {host:
|
96
|
+
environment 'config.action_mailer.default_url_options = {host: "http://yourwebsite.example.com"}', env: 'production'
|
95
97
|
```
|
96
98
|
|
97
99
|
A block can be used in place of the `data` argument.
|
98
100
|
|
99
101
|
### vendor/lib/file/initializer(filename, data = nil, &block)
|
100
102
|
|
101
|
-
Adds an initializer to the generated application
|
103
|
+
Adds an initializer to the generated application's `config/initializers` directory.
|
102
104
|
|
103
105
|
Let's say you like using `Object#not_nil?` and `Object#not_blank?`:
|
104
106
|
|
@@ -127,7 +129,7 @@ file 'app/components/foo.rb', <<-CODE
|
|
127
129
|
CODE
|
128
130
|
```
|
129
131
|
|
130
|
-
That
|
132
|
+
That'll create the `app/components` directory and put `foo.rb` in there.
|
131
133
|
|
132
134
|
### rakefile(filename, data = nil, &block)
|
133
135
|
|
@@ -197,7 +199,7 @@ end
|
|
197
199
|
|
198
200
|
### ask(question)
|
199
201
|
|
200
|
-
`ask()` gives you a chance to get some feedback from the user and use it in your templates. Let's say you want your user to name the new shiny library you
|
202
|
+
`ask()` gives you a chance to get some feedback from the user and use it in your templates. Let's say you want your user to name the new shiny library you're adding:
|
201
203
|
|
202
204
|
```ruby
|
203
205
|
lib_name = ask("What do you want to call the shiny library ?")
|
@@ -211,7 +213,7 @@ CODE
|
|
211
213
|
|
212
214
|
### yes?(question) or no?(question)
|
213
215
|
|
214
|
-
These methods let you ask questions from templates and decide the flow based on the user
|
216
|
+
These methods let you ask questions from templates and decide the flow based on the user's answer. Let's say you want to freeze rails only if the user wants to:
|
215
217
|
|
216
218
|
```ruby
|
217
219
|
rake("rails:freeze:gems") if yes?("Freeze rails gems?")
|
@@ -227,3 +229,38 @@ git :init
|
|
227
229
|
git add: "."
|
228
230
|
git commit: "-a -m 'Initial commit'"
|
229
231
|
```
|
232
|
+
|
233
|
+
### after_bundle(&block)
|
234
|
+
|
235
|
+
Registers a callback to be executed after the gems are bundled and binstubs
|
236
|
+
are generated. Useful for all generated files to version control:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
after_bundle do
|
240
|
+
git :init
|
241
|
+
git add: '.'
|
242
|
+
git commit: "-a -m 'Initial commit'"
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
The callbacks gets executed even if `--skip-bundle` and/or `--skip-spring` has
|
247
|
+
been passed.
|
248
|
+
|
249
|
+
Advanced Usage
|
250
|
+
--------------
|
251
|
+
|
252
|
+
The application template is evaluated in the context of a
|
253
|
+
`Rails::Generators::AppGenerator` instance. It uses the `apply` action
|
254
|
+
provided by
|
255
|
+
[Thor](https://github.com/erikhuda/thor/blob/master/lib/thor/actions.rb#L207).
|
256
|
+
This means you can extend and change the instance to match your needs.
|
257
|
+
|
258
|
+
For example by overwriting the `source_paths` method to contain the
|
259
|
+
location of your template. Now methods like `copy_file` will accept
|
260
|
+
relative paths to your template's location.
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
def source_paths
|
264
|
+
[File.expand_path(File.dirname(__FILE__))]
|
265
|
+
end
|
266
|
+
```
|