railties 3.1.0.rc4 → 3.1.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -9
- data/bin/rails +2 -0
- data/guides/assets/images/rails_welcome.png +0 -0
- data/guides/rails_guides/generator.rb +1 -1
- data/guides/rails_guides/textile_extensions.rb +18 -17
- data/guides/source/3_0_release_notes.textile +21 -21
- data/guides/source/action_controller_overview.textile +1 -1
- data/guides/source/action_mailer_basics.textile +27 -6
- data/guides/source/action_view_overview.textile +6 -6
- data/guides/source/active_record_querying.textile +77 -7
- data/guides/source/active_record_validations_callbacks.textile +78 -81
- data/guides/source/active_support_core_extensions.textile +87 -31
- data/guides/source/ajax_on_rails.textile +1 -1
- data/guides/source/api_documentation_guidelines.textile +12 -8
- data/guides/source/asset_pipeline.textile +416 -0
- data/guides/source/association_basics.textile +2 -4
- data/guides/source/caching_with_rails.textile +7 -6
- data/guides/source/command_line.textile +78 -116
- data/guides/source/configuring.textile +34 -17
- data/guides/source/contribute.textile +1 -1
- data/guides/source/contributing_to_ruby_on_rails.textile +3 -3
- data/guides/source/debugging_rails_applications.textile +2 -2
- data/guides/source/form_helpers.textile +40 -51
- data/guides/source/getting_started.textile +641 -197
- data/guides/source/initialization.textile +4 -4
- data/guides/source/layouts_and_rendering.textile +2 -2
- data/guides/source/migrations.textile +114 -32
- data/guides/source/nested_model_forms.textile +6 -6
- data/guides/source/performance_testing.textile +6 -6
- data/guides/source/plugins.textile +23 -22
- data/guides/source/rails_application_templates.textile +8 -14
- data/guides/source/routing.textile +57 -51
- data/guides/source/ruby_on_rails_guides_guidelines.textile +3 -3
- data/guides/source/security.textile +10 -10
- data/guides/source/testing.textile +1 -1
- data/lib/rails.rb +27 -1
- data/lib/rails/all.rb +1 -0
- data/lib/rails/application.rb +4 -10
- data/lib/rails/application/configuration.rb +3 -12
- data/lib/rails/application/railties.rb +1 -1
- data/lib/rails/engine.rb +53 -42
- data/lib/rails/generators.rb +1 -1
- data/lib/rails/generators/app_base.rb +36 -15
- data/lib/rails/generators/generated_attribute.rb +1 -1
- data/lib/rails/generators/js/assets/assets_generator.rb +13 -0
- data/lib/rails/generators/js/assets/templates/javascript.js +2 -0
- data/lib/rails/generators/rails/app/app_generator.rb +3 -1
- data/lib/rails/generators/rails/app/templates/Gemfile +11 -7
- data/lib/rails/generators/rails/app/templates/config/application.rb +7 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +62 -0
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +3 -12
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +3 -3
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +0 -3
- data/lib/rails/generators/rails/assets/assets_generator.rb +2 -9
- data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +12 -10
- data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +5 -2
- data/lib/rails/generators/rails/plugin_new/templates/Gemfile +6 -3
- data/lib/rails/generators/rails/plugin_new/templates/Rakefile +5 -1
- data/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt +14 -0
- data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +5 -3
- data/lib/rails/info.rb +4 -0
- data/lib/rails/paths.rb +5 -5
- data/lib/rails/railtie.rb +4 -4
- data/lib/rails/tasks.rb +0 -1
- data/lib/rails/tasks/documentation.rake +3 -3
- data/lib/rails/tasks/engine.rake +2 -0
- data/lib/rails/tasks/framework.rake +3 -3
- data/lib/rails/tasks/tmp.rake +1 -1
- data/lib/rails/test_unit/testing.rake +2 -2
- data/lib/rails/version.rb +1 -1
- metadata +19 -33
- data/lib/rails/generators/rails/assets/templates/javascript.js.coffee +0 -3
- data/lib/rails/tasks/assets.rake +0 -21
@@ -512,7 +512,7 @@ h4. +railties/lib/rails/ruby_version_check.rb+
|
|
512
512
|
|
513
513
|
This file simply checks if the Ruby version is less than 1.8.7 or is 1.9.1 and raises an error if that is the case. Rails 3 simply will not run on earlier versions of Ruby than 1.8.7 or 1.9.1.
|
514
514
|
|
515
|
-
NOTE: You should always
|
515
|
+
NOTE: You should always endeavor to run the latest version of Ruby with your Rails applications. The benefits are many, including security fixes and the like, and very often there is a speed increase associated with it. The caveat is that you could have code that potentially breaks on the latest version, which should be fixed to work on the latest version rather than kept around as an excuse not to upgrade.
|
516
516
|
|
517
517
|
h4. +active_support/core_ext/kernel/reporting.rb+
|
518
518
|
|
@@ -661,9 +661,9 @@ require 'active_support/inflections'
|
|
661
661
|
require 'active_support/core_ext/string/inflections'
|
662
662
|
</ruby>
|
663
663
|
|
664
|
-
The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here.
|
664
|
+
The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here. The +activesupport/lib/active_support/inflector/inflections.rb+ is required by +active_support/inflector/methods+.
|
665
665
|
|
666
|
-
h4. +
|
666
|
+
h4. +active_support/inflections+
|
667
667
|
|
668
668
|
This file references the +ActiveSupport::Inflector+ constant which isn't loaded by this point. But there were autoloads set up in +activesupport/lib/active_support.rb+ which will load the file which loads this constant and so then it will be defined. Then this file defines pluralization and singularization rules for words in Rails. This is how Rails knows how to pluralize "tomato" to "tomatoes".
|
669
669
|
|
@@ -866,7 +866,7 @@ def +(other)
|
|
866
866
|
end
|
867
867
|
</ruby>
|
868
868
|
|
869
|
-
So this <tt>+</tt> method is
|
869
|
+
So this <tt>+</tt> method is overridden to return a new collection comprising of the existing collection as an array and then using the <tt>Array#+</tt> method combines these two collections, returning a "super" +Collection+ object. In this case, the only initializer that's going to be in this new +Collection+ object is the +i18n.callbacks+ initializer.
|
870
870
|
|
871
871
|
The next method to be called after this +initializer+ method is the +after_initialize+ method on the +config+ object, which is defined like this:
|
872
872
|
|
@@ -94,7 +94,7 @@ NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandler
|
|
94
94
|
|
95
95
|
h4. Using +render+
|
96
96
|
|
97
|
-
In most cases, the +ActionController::Base#render+ method does the heavy lifting of rendering your application's content for use by a browser. There are a variety of ways to
|
97
|
+
In most cases, the +ActionController::Base#render+ method does the heavy lifting of rendering your application's content for use by a browser. There are a variety of ways to customize the behaviour of +render+. You can render the default view for a Rails template, or a specific template, or a file, or inline code, or nothing at all. You can render text, JSON, or XML. You can specify the content type or HTTP status of the rendered response as well.
|
98
98
|
|
99
99
|
TIP: If you want to see the exact results of a call to +render+ without needing to inspect it in a browser, you can call +render_to_string+. This method takes exactly the same options as +render+, but it returns a string instead of sending a response back to the browser.
|
100
100
|
|
@@ -123,7 +123,7 @@ Cache-Control: no-cache
|
|
123
123
|
$
|
124
124
|
</shell>
|
125
125
|
|
126
|
-
We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an
|
126
|
+
We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgment that the request was completed.
|
127
127
|
|
128
128
|
TIP: You should probably be using the +head+ method, discussed later in this guide, instead of +render :nothing+. This provides additional flexibility and makes it explicit that you're only generating HTTP headers.
|
129
129
|
|
@@ -17,7 +17,7 @@ endprologue.
|
|
17
17
|
|
18
18
|
h3. Anatomy of a Migration
|
19
19
|
|
20
|
-
Before
|
20
|
+
Before we dive into the details of a migration, here are a few examples of the sorts of things you can do:
|
21
21
|
|
22
22
|
<ruby>
|
23
23
|
class CreateProducts < ActiveRecord::Migration
|
@@ -117,6 +117,33 @@ Occasionally you will make a mistake when writing a migration. If you have alrea
|
|
117
117
|
|
118
118
|
In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless.
|
119
119
|
|
120
|
+
h4. Supported Types
|
121
|
+
|
122
|
+
Active Record supports the following types:
|
123
|
+
|
124
|
+
* +:primary_key+
|
125
|
+
* +:string+
|
126
|
+
* +:text+
|
127
|
+
* +:integer+
|
128
|
+
* +:float+
|
129
|
+
* +:decimal+
|
130
|
+
* +:datetime+
|
131
|
+
* +:timestamp+
|
132
|
+
* +:time+
|
133
|
+
* +:date+
|
134
|
+
* +:binary+
|
135
|
+
* +:boolean+
|
136
|
+
|
137
|
+
These will be mapped onto an appropriate underlying database type, for example with MySQL +:string+ is mapped to +VARCHAR(255)+. You can create columns of types not supported by Active Record when using the non-sexy syntax, for example
|
138
|
+
|
139
|
+
<ruby>
|
140
|
+
create_table :products do |t|
|
141
|
+
t.column :name, 'polygon', :null => false
|
142
|
+
end
|
143
|
+
</ruby>
|
144
|
+
|
145
|
+
This may however hinder portability to other databases.
|
146
|
+
|
120
147
|
h3. Creating a Migration
|
121
148
|
|
122
149
|
h4. Creating a Model
|
@@ -261,18 +288,6 @@ end
|
|
261
288
|
|
262
289
|
will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table (when using MySQL the default is +ENGINE=InnoDB+).
|
263
290
|
|
264
|
-
The types supported by Active Record are +:primary_key+, +:string+, +:text+, +:integer+, +:float+, +:decimal+, +:datetime+, +:timestamp+, +:time+, +:date+, +:binary+, +:boolean+.
|
265
|
-
|
266
|
-
These will be mapped onto an appropriate underlying database type, for example with MySQL +:string+ is mapped to +VARCHAR(255)+. You can create columns of types not supported by Active Record when using the non-sexy syntax, for example
|
267
|
-
|
268
|
-
<ruby>
|
269
|
-
create_table :products do |t|
|
270
|
-
t.column :name, 'polygon', :null => false
|
271
|
-
end
|
272
|
-
</ruby>
|
273
|
-
|
274
|
-
This may however hinder portability to other databases.
|
275
|
-
|
276
291
|
h4. Changing Tables
|
277
292
|
|
278
293
|
A close cousin of +create_table+ is +change_table+, used for changing existing tables. It is used in a similar fashion to +create_table+ but the object yielded to the block knows more tricks. For example
|
@@ -344,7 +359,7 @@ The +change+ method removes the need to write both +up+ and +down+ methods in th
|
|
344
359
|
|
345
360
|
* +add_column+
|
346
361
|
* +add_index+
|
347
|
-
* +
|
362
|
+
* +add_timestamps+
|
348
363
|
* +create_table+
|
349
364
|
* +remove_timestamps+
|
350
365
|
* +rename_column+
|
@@ -462,7 +477,7 @@ Several methods are provided that allow you to control all this:
|
|
462
477
|
|
463
478
|
For example, this migration
|
464
479
|
|
465
|
-
<
|
480
|
+
<pre>
|
466
481
|
class CreateProducts < ActiveRecord::Migration
|
467
482
|
def change
|
468
483
|
suppress_messages do
|
@@ -481,7 +496,7 @@ class CreateProducts < ActiveRecord::Migration
|
|
481
496
|
end
|
482
497
|
end
|
483
498
|
end
|
484
|
-
</
|
499
|
+
</pre>
|
485
500
|
|
486
501
|
generates the following output
|
487
502
|
|
@@ -499,40 +514,107 @@ If you just want Active Record to shut up then running +rake db:migrate VERBOSE=
|
|
499
514
|
|
500
515
|
h3. Using Models in Your Migrations
|
501
516
|
|
502
|
-
When creating or updating data in a migration it is often tempting to use one of your models. After all they exist to provide easy access to the underlying data. This can be done but some caution should be observed.
|
517
|
+
When creating or updating data in a migration it is often tempting to use one of your models. After all they exist to provide easy access to the underlying data. This can be done, but some caution should be observed.
|
503
518
|
|
504
|
-
|
519
|
+
For example, problems occur when the model uses database columns which are (1) not currently in the database and (2) will be created by this or a subsequent migration.
|
505
520
|
|
506
|
-
|
521
|
+
Consider this example, where Alice and Bob are working on the same code base which contains a +Product+ model:
|
507
522
|
|
508
|
-
|
509
|
-
|
510
|
-
|
523
|
+
Bob goes on vacation.
|
524
|
+
|
525
|
+
Alice creates a migration for the +products+ table which adds a new column and initializes it.
|
526
|
+
She also adds a validation to the Product model for the new column.
|
527
|
+
|
528
|
+
<pre>
|
529
|
+
# db/migrate/20100513121110_add_flag_to_product.rb
|
530
|
+
|
531
|
+
class AddFlagToProduct < ActiveRecord::Migration
|
532
|
+
def change
|
533
|
+
add_column :products, :flag, :int
|
534
|
+
Product.all.each { |f| f.update_attributes!(:flag => 'false') }
|
511
535
|
end
|
536
|
+
end
|
537
|
+
</pre>
|
538
|
+
|
539
|
+
<pre>
|
540
|
+
# app/model/product.rb
|
541
|
+
|
542
|
+
class Product < ActiveRecord::Base
|
543
|
+
validates_presence_of :flag
|
544
|
+
end
|
545
|
+
</pre>
|
546
|
+
|
547
|
+
Alice adds a second migration which adds and initializes another column to the +products+ table and also adds a validation to the Product model for the new column.
|
512
548
|
|
549
|
+
<pre>
|
550
|
+
# db/migrate/20100515121110_add_fuzz_to_product.rb
|
551
|
+
|
552
|
+
class AddFuzzToProduct < ActiveRecord::Migration
|
513
553
|
def change
|
514
|
-
|
554
|
+
add_column :products, :fuzz, :string
|
555
|
+
Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
|
515
556
|
end
|
516
557
|
end
|
517
|
-
</
|
518
|
-
The migration has its own minimal copy of the +Product+ model and no longer cares about the +Product+ model defined in the application.
|
558
|
+
</pre>
|
519
559
|
|
520
|
-
|
560
|
+
<pre>
|
561
|
+
# app/model/product.rb
|
521
562
|
|
522
|
-
|
563
|
+
class Product < ActiveRecord::Base
|
564
|
+
validates_presence_of :flag
|
565
|
+
validates_presence_of :fuzz
|
566
|
+
end
|
567
|
+
</pre>
|
523
568
|
|
524
|
-
|
525
|
-
|
569
|
+
Both migrations work for Alice.
|
570
|
+
|
571
|
+
Bob comes back from vacation and:
|
572
|
+
|
573
|
+
# updates the source - which contains both migrations and the latests version of the Product model.
|
574
|
+
# runs outstanding migrations with +rake db:migrate+, which includes the one that updates the +Product+ model.
|
575
|
+
|
576
|
+
The migration crashes because when the model attempts to save, it tries to validate the second added column, which is not in the database when the _first_ migration runs.
|
577
|
+
|
578
|
+
<pre>
|
579
|
+
rake aborted!
|
580
|
+
An error has occurred, this and all later migrations canceled:
|
581
|
+
|
582
|
+
undefined method `fuzz' for #<Product:0x000001049b14a0>
|
583
|
+
</pre>
|
584
|
+
|
585
|
+
A fix for this is to create a local model within the migration. This keeps rails from running the validations, so that the migrations run to completion.
|
586
|
+
|
587
|
+
When using a faux model, it's a good idea to call +Product.reset_column_information+ to refresh the ActiveRecord cache for the Product model prior to updating data in the database.
|
588
|
+
|
589
|
+
If Alice had done this instead, there would have been no problem:
|
590
|
+
|
591
|
+
<pre>
|
592
|
+
# db/migrate/20100513121110_add_flag_to_product.rb
|
593
|
+
|
594
|
+
class AddFlagToProduct < ActiveRecord::Migration
|
526
595
|
class Product < ActiveRecord::Base
|
527
596
|
end
|
597
|
+
def change
|
598
|
+
add_column :products, :flag, :int
|
599
|
+
Product.reset_column_information
|
600
|
+
Product.all.each { |f| f.update_attributes!(:flag => false) }
|
601
|
+
end
|
602
|
+
end
|
603
|
+
</pre>
|
604
|
+
|
605
|
+
<pre>
|
606
|
+
# db/migrate/20100515121110_add_fuzz_to_product.rb
|
528
607
|
|
608
|
+
class AddFuzzToProduct < ActiveRecord::Migration
|
609
|
+
class Product < ActiveRecord::Base
|
610
|
+
end
|
529
611
|
def change
|
530
|
-
add_column :
|
612
|
+
add_column :products, :fuzz, :string
|
531
613
|
Product.reset_column_information
|
532
|
-
|
614
|
+
Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
|
533
615
|
end
|
534
616
|
end
|
535
|
-
</
|
617
|
+
</pre>
|
536
618
|
|
537
619
|
|
538
620
|
h3. Schema Dumping and You
|
@@ -90,7 +90,7 @@ h3. Views
|
|
90
90
|
|
91
91
|
h4. Controller code
|
92
92
|
|
93
|
-
A nested model form will _only_ be
|
93
|
+
A nested model form will _only_ be built if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first.
|
94
94
|
|
95
95
|
Consider the following typical RESTful controller which will prepare a new Person instance and its +address+ and +projects+ associations before rendering the +new+ template:
|
96
96
|
|
@@ -144,7 +144,7 @@ Now add a nested form for the +address+ association:
|
|
144
144
|
<%= f.text_field :name %>
|
145
145
|
|
146
146
|
<%= f.fields_for :address do |af| %>
|
147
|
-
<%=
|
147
|
+
<%= af.text_field :street %>
|
148
148
|
<% end %>
|
149
149
|
<% end %>
|
150
150
|
</erb>
|
@@ -159,7 +159,7 @@ This generates:
|
|
159
159
|
</form>
|
160
160
|
</html>
|
161
161
|
|
162
|
-
Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be
|
162
|
+
Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be built by the way it has namespaced the +name+ attribute.
|
163
163
|
|
164
164
|
When this form is posted the Rails parameter parser will construct a hash like the following:
|
165
165
|
|
@@ -185,7 +185,7 @@ The form code for an association collection is pretty similar to that of a singl
|
|
185
185
|
<%= f.text_field :name %>
|
186
186
|
|
187
187
|
<%= f.fields_for :projects do |pf| %>
|
188
|
-
<%=
|
188
|
+
<%= pf.text_field :name %>
|
189
189
|
<% end %>
|
190
190
|
<% end %>
|
191
191
|
</erb>
|
@@ -201,7 +201,7 @@ Which generates:
|
|
201
201
|
</form>
|
202
202
|
</html>
|
203
203
|
|
204
|
-
As you can see it has generated 2 +project name+ inputs, one for each new +project+ that
|
204
|
+
As you can see it has generated 2 +project name+ inputs, one for each new +project+ that was built in the controller's +new+ action. Only this time the +name+ attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as:
|
205
205
|
|
206
206
|
<ruby>
|
207
207
|
{
|
@@ -215,7 +215,7 @@ As you can see it has generated 2 +project name+ inputs, one for each new +proje
|
|
215
215
|
}
|
216
216
|
</ruby>
|
217
217
|
|
218
|
-
You can basically see the +projects_attributes+ hash as an array of attribute hashes
|
218
|
+
You can basically see the +projects_attributes+ hash as an array of attribute hashes, one for each model instance.
|
219
219
|
|
220
220
|
NOTE: The reason that +fields_for+ constructed a form which would result in a hash instead of an array is that it won't work for any forms nested deeper than one level deep.
|
221
221
|
|
@@ -66,7 +66,7 @@ resources :posts
|
|
66
66
|
# home_controller.rb
|
67
67
|
class HomeController < ApplicationController
|
68
68
|
def dashboard
|
69
|
-
@users = User.last_ten(:
|
69
|
+
@users = User.last_ten.includes(:avatars)
|
70
70
|
@posts = Post.all_today
|
71
71
|
end
|
72
72
|
end
|
@@ -151,7 +151,7 @@ Performance tests can be run in two modes: Benchmarking and Profiling.
|
|
151
151
|
|
152
152
|
h5. Benchmarking
|
153
153
|
|
154
|
-
Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run
|
154
|
+
Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run *4 times* in benchmarking mode.
|
155
155
|
|
156
156
|
To run performance tests in benchmarking mode:
|
157
157
|
|
@@ -161,7 +161,7 @@ $ rake test:benchmark
|
|
161
161
|
|
162
162
|
h5. Profiling
|
163
163
|
|
164
|
-
Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run
|
164
|
+
Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run *once* in profiling mode.
|
165
165
|
|
166
166
|
To run performance tests in profiling mode:
|
167
167
|
|
@@ -276,7 +276,7 @@ measurement,created_at,app,rails,ruby,platform
|
|
276
276
|
|
277
277
|
h5(#output-profiling). Profiling
|
278
278
|
|
279
|
-
In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is
|
279
|
+
In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependent on the interpreter in use. A brief description of each type and their availability across interpreters is given below.
|
280
280
|
|
281
281
|
h6. Command Line
|
282
282
|
|
@@ -481,7 +481,7 @@ h4. +profiler+
|
|
481
481
|
Usage:
|
482
482
|
|
483
483
|
<shell>
|
484
|
-
Usage: rails
|
484
|
+
Usage: rails profiler 'Ruby.code' 'Ruby.more_code' ... [OPTS]
|
485
485
|
-r, --runs N Number of runs.
|
486
486
|
Default: 1
|
487
487
|
-o, --output PATH Directory to use when writing the results.
|
@@ -573,7 +573,7 @@ h3. Useful Links
|
|
573
573
|
h4. Rails Plugins and Gems
|
574
574
|
|
575
575
|
* "Rails Analyzer":http://rails-analyzer.rubyforge.org
|
576
|
-
* "Palmist":http://www.flyingmachinestudios.com/
|
576
|
+
* "Palmist":http://www.flyingmachinestudios.com/programming/announcing-palmist
|
577
577
|
* "Rails Footnotes":https://github.com/josevalim/rails-footnotes/tree/master
|
578
578
|
* "Query Reviewer":https://github.com/dsboulder/query_reviewer/tree/master
|
579
579
|
|
@@ -25,33 +25,36 @@ endprologue.
|
|
25
25
|
|
26
26
|
h3. Setup
|
27
27
|
|
28
|
-
|
28
|
+
Before you continue, take a moment to decide if your new plugin will be potentially shared across different Rails applications.
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
* If your plugin is specific to your application, your new plugin will be a _vendored plugin_.
|
31
|
+
* If you think your plugin may be used across applications, build it as a _gemified plugin_.
|
32
|
+
|
33
|
+
h4. Either generate a vendored plugin...
|
34
|
+
|
35
|
+
Use the +rails generate plugin+ command in your Rails root directory
|
36
|
+
to create a new plugin that will live in the +vendor/plugins+
|
37
|
+
directory. See usage and options by asking for help:
|
32
38
|
|
33
39
|
<shell>
|
34
40
|
$ rails generate plugin --help
|
35
41
|
</shell>
|
36
42
|
|
37
|
-
|
43
|
+
h4. Or generate a gemified plugin.
|
38
44
|
|
39
|
-
|
40
|
-
|
41
|
-
|
45
|
+
Writing your Rails plugin as a gem, rather than as a vendored plugin,
|
46
|
+
lets you share your plugin across different rails applications using
|
47
|
+
RubyGems and Bundler.
|
42
48
|
|
43
|
-
Rails 3.1
|
44
|
-
|
45
|
-
|
49
|
+
Rails 3.1 ships with a +rails plugin new+ command which creates a
|
50
|
+
skeleton for developing any kind of Rails extension with the ability
|
51
|
+
to run integration tests using a dummy Rails application. See usage
|
52
|
+
and options by asking for help:
|
46
53
|
|
47
54
|
<shell>
|
48
|
-
$
|
49
|
-
$ enginex --help
|
50
|
-
$ enginex yaffle
|
55
|
+
$ rails plugin --help
|
51
56
|
</shell>
|
52
57
|
|
53
|
-
This command will create a new directory named "yaffle" within the current directory.
|
54
|
-
|
55
58
|
h3. Testing your newly generated plugin
|
56
59
|
|
57
60
|
You can navigate to the directory that contains the plugin, run the +bundle install+ command
|
@@ -83,7 +86,7 @@ class CoreExtTest < Test::Unit::TestCase
|
|
83
86
|
end
|
84
87
|
</ruby>
|
85
88
|
|
86
|
-
Run +rake+ to run the test. This test should fail because we haven't implemented the +
|
89
|
+
Run +rake+ to run the test. This test should fail because we haven't implemented the +to_squawk+ method:
|
87
90
|
|
88
91
|
<shell>
|
89
92
|
1) Error:
|
@@ -215,8 +218,8 @@ test/dummy directory:
|
|
215
218
|
|
216
219
|
<shell>
|
217
220
|
$ cd test/dummy
|
218
|
-
$ rails generate model Hickwall
|
219
|
-
$ rails generate model Wickwall
|
221
|
+
$ rails generate model Hickwall last_squawk:string
|
222
|
+
$ rails generate model Wickwall last_squawk:string last_tweet:string
|
220
223
|
</shell>
|
221
224
|
|
222
225
|
Now you can create the necessary database tables in your testing database by navigating to your dummy app
|
@@ -319,7 +322,7 @@ When you run +rake+ you should see the tests all pass:
|
|
319
322
|
|
320
323
|
h4. Add an Instance Method
|
321
324
|
|
322
|
-
This plugin will add a method named 'squawk' to any Active Record objects that call 'acts_as_yaffle'.
|
325
|
+
This plugin will add a method named 'squawk' to any Active Record objects that call 'acts_as_yaffle'. The 'squawk'
|
323
326
|
method will simply set the value of one of the fields in the database.
|
324
327
|
|
325
328
|
To start out, write a failing test that shows the behavior you'd like:
|
@@ -387,9 +390,7 @@ Run +rake+ one final time and you should see:
|
|
387
390
|
7 tests, 7 assertions, 0 failures, 0 errors, 0 skips
|
388
391
|
</shell>
|
389
392
|
|
390
|
-
NOTE: The use of +write_attribute+ to write to the field in model is just one example of how a plugin can
|
391
|
-
interact with the model, and will not always be the right method to use. For example, you could also
|
392
|
-
use +send("#{self.class.yaffle_text_field}=", string.to_squawk)+.
|
393
|
+
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 <tt>send("#{self.class.yaffle_text_field}=", string.to_squawk)</tt>.
|
393
394
|
|
394
395
|
h3. Generators
|
395
396
|
|