From 53cd102b39eb62567298430cbd94e40dd78d46a0 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 24 Feb 2009 12:29:25 +0000 Subject: Merge with docrails --- activerecord/lib/active_record/associations.rb | 65 +++++++--------- activerecord/lib/active_record/base.rb | 3 +- activerecord/lib/active_record/callbacks.rb | 38 +++++++-- activerecord/lib/active_record/fixtures.rb | 103 +++++++++++-------------- 4 files changed, 110 insertions(+), 99 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 05ce8ff0b5..e2dc883b1b 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -133,41 +133,40 @@ module ActiveRecord # | | belongs_to | # generated methods | belongs_to | :polymorphic | has_one # ----------------------------------+------------+--------------+--------- - # #other | X | X | X - # #other=(other) | X | X | X - # #build_other(attributes={}) | X | | X - # #create_other(attributes={}) | X | | X - # #other.create!(attributes={}) | | | X - # #other.nil? | X | X | + # other | X | X | X + # other=(other) | X | X | X + # build_other(attributes={}) | X | | X + # create_other(attributes={}) | X | | X + # other.create!(attributes={}) | | | X # # ===Collection associations (one-to-many / many-to-many) # | | | has_many # generated methods | habtm | has_many | :through # ----------------------------------+-------+----------+---------- - # #others | X | X | X - # #others=(other,other,...) | X | X | X - # #other_ids | X | X | X - # #other_ids=(id,id,...) | X | X | X - # #others<< | X | X | X - # #others.push | X | X | X - # #others.concat | X | X | X - # #others.build(attributes={}) | X | X | X - # #others.create(attributes={}) | X | X | X - # #others.create!(attributes={}) | X | X | X - # #others.size | X | X | X - # #others.length | X | X | X - # #others.count | X | X | X - # #others.sum(args*,&block) | X | X | X - # #others.empty? | X | X | X - # #others.clear | X | X | X - # #others.delete(other,other,...) | X | X | X - # #others.delete_all | X | X | - # #others.destroy_all | X | X | X - # #others.find(*args) | X | X | X - # #others.find_first | X | | - # #others.exists? | X | X | X - # #others.uniq | X | X | X - # #others.reset | X | X | X + # others | X | X | X + # others=(other,other,...) | X | X | X + # other_ids | X | X | X + # other_ids=(id,id,...) | X | X | X + # others<< | X | X | X + # others.push | X | X | X + # others.concat | X | X | X + # others.build(attributes={}) | X | X | X + # others.create(attributes={}) | X | X | X + # others.create!(attributes={}) | X | X | X + # others.size | X | X | X + # others.length | X | X | X + # others.count | X | X | X + # others.sum(args*,&block) | X | X | X + # others.empty? | X | X | X + # others.clear | X | X | X + # others.delete(other,other,...) | X | X | X + # others.delete_all | X | X | + # others.destroy_all | X | X | X + # others.find(*args) | X | X | X + # others.find_first | X | | + # others.exists? | X | X | X + # others.uniq | X | X | X + # others.reset | X | X | X # # == Cardinality and associations # @@ -813,8 +812,6 @@ module ActiveRecord # [association=(associate)] # Assigns the associate object, extracts the primary key, sets it as the foreign key, # and saves the associate object. - # [association.nil?] - # Returns +true+ if there is no associated object. # [build_association(attributes = {})] # Returns a new object of the associated type that has been instantiated # with +attributes+ and linked to this object through a foreign key, but has not @@ -833,7 +830,6 @@ module ActiveRecord # An Account class declares has_one :beneficiary, which will add: # * Account#beneficiary (similar to Beneficiary.find(:first, :conditions => "account_id = #{id}")) # * Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save) - # * Account#beneficiary.nil? # * Account#build_beneficiary (similar to Beneficiary.new("account_id" => id)) # * Account#create_beneficiary (similar to b = Beneficiary.new("account_id" => id); b.save; b) # @@ -934,8 +930,6 @@ module ActiveRecord # Returns the associated object. +nil+ is returned if none is found. # [association=(associate)] # Assigns the associate object, extracts the primary key, and sets it as the foreign key. - # [association.nil?] - # Returns +true+ if there is no associated object. # [build_association(attributes = {})] # Returns a new object of the associated type that has been instantiated # with +attributes+ and linked to this object through a foreign key, but has not yet been saved. @@ -953,7 +947,6 @@ module ActiveRecord # * Post#author (similar to Author.find(author_id)) # * Post#author=(author) (similar to post.author_id = author.id) # * Post#author? (similar to post.author == some_author) - # * Post#author.nil? # * Post#build_author (similar to post.author = Author.new) # * Post#create_author (similar to post.author = Author.new; post.author.save; post.author) # The declaration can also include an options hash to specialize the behavior of the association. diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 982342e509..55ab1facf2 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -886,7 +886,8 @@ module ActiveRecord #:nodoc: # Deletes the records matching +conditions+ without instantiating the records first, and hence not # calling the +destroy+ method nor invoking callbacks. This is a single SQL DELETE statement that # goes straight to the database, much more efficient than +destroy_all+. Be careful with relations - # though, in particular :dependent rules defined on associations are not honored. + # though, in particular :dependent rules defined on associations are not honored. Returns + # the number of rows affected. # # ==== Parameters # diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 88958f4583..e375037b5b 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -104,6 +104,37 @@ module ActiveRecord # The callback objects have methods named after the callback called with the record as the only parameter, such as: # # class BankAccount < ActiveRecord::Base + # before_save EncryptionWrapper.new + # after_save EncryptionWrapper.new + # after_initialize EncryptionWrapper.new + # end + # + # class EncryptionWrapper + # def before_save(record) + # record.credit_card_number = encrypt(record.credit_card_number) + # end + # + # def after_save(record) + # record.credit_card_number = decrypt(record.credit_card_number) + # end + # + # alias_method :after_find, :after_save + # + # private + # def encrypt(value) + # # Secrecy is committed + # end + # + # def decrypt(value) + # # Secrecy is unveiled + # end + # end + # + # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has + # a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other + # initialization data such as the name of the attribute to work with: + # + # class BankAccount < ActiveRecord::Base # before_save EncryptionWrapper.new("credit_card_number") # after_save EncryptionWrapper.new("credit_card_number") # after_initialize EncryptionWrapper.new("credit_card_number") @@ -115,11 +146,11 @@ module ActiveRecord # end # # def before_save(record) - # record.credit_card_number = encrypt(record.credit_card_number) + # record.send("#{@attribute}=", encrypt(record.send("#{@attribute}"))) # end # # def after_save(record) - # record.credit_card_number = decrypt(record.credit_card_number) + # record.send("#{@attribute}=", decrypt(record.send("#{@attribute}"))) # end # # alias_method :after_find, :after_save @@ -134,9 +165,6 @@ module ActiveRecord # end # end # - # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has - # a method by the name of the callback messaged. - # # The callback macros usually accept a symbol for the method they're supposed to run, but you can also pass a "method string", # which will then be evaluated within the binding of the callback. Example: # diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 0131d9fac5..c6501113bf 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -21,13 +21,17 @@ else end end -# Fixtures are a way of organizing data that you want to test against; in short, sample data. They come in 3 flavors: +# Fixtures are a way of organizing data that you want to test against; in short, sample data. +# +# = Fixture formats +# +# Fixtures come in 3 flavors: # # 1. YAML fixtures # 2. CSV fixtures # 3. Single-file fixtures # -# = YAML fixtures +# == YAML fixtures # # This type of fixture is in YAML format and the preferred default. YAML is a file format which describes data structures # in a non-verbose, human-readable format. It ships with Ruby 1.8.1+. @@ -65,9 +69,9 @@ end # parent_id: 1 # title: Child # -# = CSV fixtures +# == CSV fixtures # -# Fixtures can also be kept in the Comma Separated Value format. Akin to YAML fixtures, CSV fixtures are stored +# Fixtures can also be kept in the Comma Separated Value (CSV) format. Akin to YAML fixtures, CSV fixtures are stored # in a single file, but instead end with the .csv file extension # (Rails example: /test/fixtures/web_sites.csv). # @@ -90,7 +94,7 @@ end # Most databases and spreadsheets support exporting to CSV format, so this is a great format for you to choose if you # have existing data somewhere already. # -# = Single-file fixtures +# == Single-file fixtures # # This type of fixture was the original format for Active Record that has since been deprecated in favor of the YAML and CSV formats. # Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory @@ -113,65 +117,53 @@ end # name => Ruby on Rails # url => http://www.rubyonrails.org # -# = Using Fixtures +# = Using fixtures in testcases # # Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the # fixtures, but first let's take a look at a sample unit test: # -# require 'web_site' +# require 'test_helper' # # class WebSiteTest < ActiveSupport::TestCase -# def test_web_site_count +# test "web_site_count" do # assert_equal 2, WebSite.count # end # end # -# As it stands, unless we pre-load the web_site table in our database with two records, this test will fail. Here's the -# easiest way to add fixtures to the database: -# -# ... -# class WebSiteTest < ActiveSupport::TestCase -# fixtures :web_sites # add more by separating the symbols with commas -# ... -# -# By adding a "fixtures" method to the test case and passing it a list of symbols (only one is shown here though), we trigger -# the testing environment to automatically load the appropriate fixtures into the database before each test. +# By default, the test_helper module will load all of your fixtures into your test database, so this test will succeed. +# The testing environment will automatically load the all fixtures into the database before each test. # To ensure consistent data, the environment deletes the fixtures before running the load. # -# In addition to being available in the database, the fixtures are also loaded into a hash stored in an instance variable -# of the test case. It is named after the symbol... so, in our example, there would be a hash available called -# @web_sites. This is where the "fixture name" comes into play. -# -# On top of that, each record is automatically "found" (using Model.find(id)) and placed in the instance variable of its name. -# So for the YAML fixtures, we'd get @rubyonrails and @google, which could be interrogated using regular Active Record semantics: +# In addition to being available in the database, the fixture's data may also be accessed by +# using a special dynamic method, which has the same name as the model, and accepts the +# name of the fixture to instantiate: # -# # test if the object created from the fixture data has the same attributes as the data itself -# def test_find -# assert_equal @web_sites["rubyonrails"]["name"], @rubyonrails.name +# test "find" do +# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name # end # -# As seen above, the data hash created from the YAML fixtures would have @web_sites["rubyonrails"]["url"] return -# "http://www.rubyonrails.org" and @web_sites["google"]["name"] would return "Google". The same fixtures, but loaded -# from a CSV fixture file, would be accessible via @web_sites["web_site_1"]["name"] == "Ruby on Rails" and have the individual -# fixtures available as instance variables @web_site_1 and @web_site_2. +# Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the following tests: # -# If you do not wish to use instantiated fixtures (usually for performance reasons) there are two options. +# test "find_alt_method_1" do +# assert_equal "Ruby on Rails", @web_sites['rubyonrails']['name'] +# end # -# - to completely disable instantiated fixtures: -# self.use_instantiated_fixtures = false +# test "find_alt_method_2" do +# assert_equal "Ruby on Rails", @rubyonrails.news +# end # -# - to keep the fixture instance (@web_sites) available, but do not automatically 'find' each instance: -# self.use_instantiated_fixtures = :no_instances +# In order to use these methods to access fixtured data within your testcases, you must specify one of the +# following in your ActiveSupport::TestCase-derived class: # -# Even if auto-instantiated fixtures are disabled, you can still access them -# by name via special dynamic methods. Each method has the same name as the -# model, and accepts the name of the fixture to instantiate: +# - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above) +# self.use_instantiated_fixtures = true # -# fixtures :web_sites +# - create only the hash for the fixtures, do not 'find' each instance (enable alternate method #1 only) +# self.use_instantiated_fixtures = :no_instances # -# def test_find -# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name -# end +# Using either of these alternate methods incurs a performance hit, as the fixtured data must be fully +# traversed in the database to create the fixture hash and/or instance variables. This is expensive for +# large sets of fixtured data. # # = Dynamic fixtures with ERb # @@ -194,21 +186,17 @@ end # = Transactional fixtures # # TestCases can use begin+rollback to isolate their changes to the database instead of having to delete+insert for every test case. -# They can also turn off auto-instantiation of fixture data since the feature is costly and often unused. # # class FooTest < ActiveSupport::TestCase # self.use_transactional_fixtures = true -# self.use_instantiated_fixtures = false -# -# fixtures :foos # -# def test_godzilla +# test "godzilla" do # assert !Foo.find(:all).empty? # Foo.destroy_all # assert Foo.find(:all).empty? # end # -# def test_godzilla_aftermath +# test "godzilla aftermath" do # assert !Foo.find(:all).empty? # end # end @@ -220,24 +208,25 @@ end # access to fixture data for every table that has been loaded through fixtures (depending on the value of +use_instantiated_fixtures+) # # When *not* to use transactional fixtures: -# 1. You're testing whether a transaction works correctly. Nested transactions don't commit until all parent transactions commit, -# particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won't be able to verify -# the results of your transaction until Active Record supports nested transactions or savepoints (in progress). -# 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM. -# Use InnoDB, MaxDB, or NDB instead. +# +# 1. You're testing whether a transaction works correctly. Nested transactions don't commit until all parent transactions commit, +# particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won't be able to verify +# the results of your transaction until Active Record supports nested transactions or savepoints (in progress). +# 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM. +# Use InnoDB, MaxDB, or NDB instead. # # = Advanced YAML Fixtures # # YAML fixtures that don't specify an ID get some extra features: # -# * Stable, autogenerated ID's +# * Stable, autogenerated IDs # * Label references for associations (belongs_to, has_one, has_many) # * HABTM associations as inline lists # * Autofilled timestamp columns # * Fixture label interpolation # * Support for YAML defaults # -# == Stable, autogenerated ID's +# == Stable, autogenerated IDs # # Here, have a monkey fixture: # @@ -292,7 +281,7 @@ end # # Add a few more monkeys and pirates and break this into multiple files, # and it gets pretty hard to keep track of what's going on. Let's -# use labels instead of ID's: +# use labels instead of IDs: # # ### in pirates.yml # -- cgit v1.2.3