diff options
Diffstat (limited to 'activerecord/lib/active_record')
9 files changed, 126 insertions, 16 deletions
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index af80a579d6..e41fda7a4b 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -28,7 +28,7 @@ module ActiveRecord # 'books' table is useful; the joined 'authors' data is just redundant, and # processing this redundant data takes memory and CPU time. The problem # quickly becomes worse and worse as the level of eager loading increases - # (i.e. if ActiveRecord is to eager load the associations' assocations as + # (i.e. if ActiveRecord is to eager load the associations' associations as # well). # # The second strategy is to use multiple database queries, one for each @@ -58,7 +58,7 @@ module ActiveRecord # +associations+ specifies one or more associations that you want to # preload. It may be: # - a Symbol or a String which specifies a single association name. For - # example, specifiying +:books+ allows this method to preload all books + # example, specifying +:books+ allows this method to preload all books # for an Author. # - an Array which specifies multiple association names. This array # is processed recursively. For example, specifying <tt>[:avatar, :books]</tt> diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 10ecd068d3..d3c859ccf4 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -519,13 +519,13 @@ module ActiveRecord # # Post.find(:all, :include => [ :author, :comments ], :conditions => ['comments.approved = ?', true]) # - # will result in a single SQL query with joins along the lines of: <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and + # This will result in a single SQL query with joins along the lines of: <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and # <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions like this can have unintended consequences. # In the above example posts with no approved comments are not returned at all, because the conditions apply to the SQL statement as a whole # and not just to the association. You must disambiguate column references for this fallback to happen, for example # <tt>:order => "author.name DESC"</tt> will work but <tt>:order => "name DESC"</tt> will not. # - # If you do want eagerload only some members of an association it is usually more natural to <tt>:include</tt> an association + # If you do want eager load only some members of an association it is usually more natural to <tt>:include</tt> an association # which has conditions defined on it: # # class Post < ActiveRecord::Base @@ -534,7 +534,7 @@ module ActiveRecord # # Post.find(:all, :include => :approved_comments) # - # will load posts and eager load the +approved_comments+ association, which contains only those comments that have been approved. + # This will load posts and eager load the +approved_comments+ association, which contains only those comments that have been approved. # # If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored, returning all the associated objects: # @@ -557,7 +557,7 @@ module ActiveRecord # # Address.find(:all, :include => :addressable) # - # will execute one query to load the addresses and load the addressables with one query per addressable type. + # This will execute one query to load the addresses and load the addressables with one query per addressable type. # For example if all the addressables are either of class Person or Company then a total of 3 queries will be executed. The list of # addressable types to load is determined on the back of the addresses loaded. This is not supported if Active Record has to fallback # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent @@ -641,6 +641,60 @@ module ActiveRecord # end # end # + # == Bi-directional associations + # + # When you specify an association there is usually an association on the associated model that specifies the same + # relationship in reverse. For example, with the following models: + # + # class Dungeon < ActiveRecord::Base + # has_many :traps + # has_one :evil_wizard + # end + # + # class Trap < ActiveRecord::Base + # belongs_to :dungeon + # end + # + # class EvilWizard < ActiveRecord::Base + # belongs_to :dungeon + # end + # + # The +traps+ association on +Dungeon+ and the the +dungeon+ association on +Trap+ are the inverse of each other and the + # inverse of the +dungeon+ association on +EvilWizard+ is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default, + # +ActiveRecord+ doesn't do know anything about these inverse relationships and so no object loading optimisation is possible. For example: + # + # d = Dungeon.first + # t = d.traps.first + # d.level == t.dungeon.level # => true + # d.level = 10 + # d.level == t.dungeon.level # => false + # + # The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to the same object data from the database, but are + # actually different in-memory copies of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell + # +ActiveRecord+ about inverse relationships and it will optimise object loading. For example, if we changed our model definitions to: + # + # class Dungeon < ActiveRecord::Base + # has_many :traps, :inverse_of => :dungeon + # has_one :evil_wizard, :inverse_of => :dungeon + # end + # + # class Trap < ActiveRecord::Base + # belongs_to :dungeon, :inverse_of => :traps + # end + # + # class EvilWizard < ActiveRecord::Base + # belongs_to :dungeon, :inverse_of => :evil_wizard + # end + # + # Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same in-memory instance and our final <tt>d.level == t.dungeon.level</tt> + # will return +true+. + # + # There are limitations to <tt>:inverse_of</tt> support: + # + # * does not work with <tt>:through</tt> associations. + # * does not work with <tt>:polymorphic</tt> associations. + # * for +belongs_to+ associations +has_many+ inverse associations are ignored. + # # == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt> # # If you attempt to assign an object to an association that doesn't match the inferred or specified <tt>:class_name</tt>, you'll @@ -781,6 +835,10 @@ module ActiveRecord # If false, don't validate the associated objects when saving the parent object. true by default. # [:autosave] # If true, always save any loaded members and destroy members marked for destruction, when saving the parent object. Off by default. + # [:inverse_of] + # Specifies the name of the <tt>belongs_to</tt> association on the associated object that is the inverse of this <tt>has_many</tt> + # association. Does not work in combination with <tt>:through</tt> or <tt>:as</tt> options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional assocations for more detail. # # Option examples: # has_many :comments, :order => "posted_on" @@ -890,6 +948,10 @@ module ActiveRecord # If false, don't validate the associated object when saving the parent object. +false+ by default. # [:autosave] # If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. Off by default. + # [:inverse_of] + # Specifies the name of the <tt>belongs_to</tt> association on the associated object that is the inverse of this <tt>has_one</tt> + # association. Does not work in combination with <tt>:through</tt> or <tt>:as</tt> options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional assocations for more detail. # # Option examples: # has_one :credit_card, :dependent => :destroy # destroys the associated credit card @@ -990,6 +1052,10 @@ module ActiveRecord # [:touch] # If true, the associated object will be touched (the updated_at/on attributes set to now) when this record is either saved or # destroyed. If you specify a symbol, that attribute will be updated with the current time instead of the updated_at/on attribute. + # [:inverse_of] + # Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated object that is the inverse of this <tt>belongs_to</tt> + # association. Does not work in combination with the <tt>:polymorphic</tt> options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional assocations for more detail. # # Option examples: # belongs_to :firm, :foreign_key => "client_of" @@ -1198,7 +1264,7 @@ module ActiveRecord private # Generates a join table name from two provided table names. - # The names in the join table namesme end up in lexicographic order. + # The names in the join table names end up in lexicographic order. # # join_table_name("members", "clubs") # => "clubs_members" # join_table_name("members", "special_clubs") # => "members_special_clubs" diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 84edaec15e..e67ccfb228 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -11,7 +11,7 @@ module ActiveRecord # ones created with +build+ are added to the target. So, the target may be # non-empty and still lack children waiting to be read from the database. # If you look directly to the database you cannot assume that's the entire - # collection because new records may have beed added to the target, etc. + # collection because new records may have been added to the target, etc. # # If you need to work on all current children, new and existing records, # +load_target+ and the +loaded+ flag are your friends. @@ -228,7 +228,7 @@ module ActiveRecord self end - # Destory all the records from this association. + # Destroy all the records from this association. # # See destroy for more info. def destroy_all diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index deab56e219..bb7342ca6e 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -256,6 +256,12 @@ module ActiveRecord #:nodoc: # # Student.find(:all, :conditions => { :grade => [9,11,12] }) # + # When joining tables, nested hashes or keys written in the form 'table_name.column_name' can be used to qualify the table name of a + # particular condition. For instance: + # + # Student.find(:all, :conditions => { :schools => { :type => 'public' }}, :joins => :schools) + # Student.find(:all, :conditions => { 'schools.type' => 'public' }, :joins => :schools) + # # == Overwriting default accessors # # All column values are automatically available through basic accessors on the Active Record object, but sometimes you @@ -854,7 +860,7 @@ module ActiveRecord #:nodoc: # Book.update_all "author = 'David'", "title LIKE '%Rails%'" # # # Update all avatars migrated more than a week ago - # Avatar.update_all ['migrated_at = ?, Time.now.utc], ['migrated_at > ?', 1.week.ago] + # Avatar.update_all ['migrated_at = ?', Time.now.utc], ['migrated_at > ?', 1.week.ago] # # # Update all books that match our conditions, but limit it to 5 ordered by date # Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5 @@ -1055,6 +1061,21 @@ module ActiveRecord #:nodoc: # # To start from an all-closed default and enable attributes as needed, # have a look at +attr_accessible+. + # + # If the access logic of your application is richer you can use <tt>Hash#except</tt> + # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are + # passed to Active Record. + # + # For example, it could be the case that the list of protected attributes + # for a given model depends on the role of the user: + # + # # Assumes plan_id is not protected because it depends on the role. + # params[:account] = params[:account].except(:plan_id) unless admin? + # @account.update_attributes(params[:account]) + # + # Note that +attr_protected+ is still applied to the received hash. Thus, + # with this technique you can at most _extend_ the list of protected + # attributes for a particular mass-assignment call. def attr_protected(*attributes) write_inheritable_attribute(:attr_protected, Set.new(attributes.map {|a| a.to_s}) + (protected_attributes || [])) end @@ -1088,6 +1109,21 @@ module ActiveRecord #:nodoc: # # customer.credit_rating = "Average" # customer.credit_rating # => "Average" + # + # If the access logic of your application is richer you can use <tt>Hash#except</tt> + # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are + # passed to Active Record. + # + # For example, it could be the case that the list of accessible attributes + # for a given model depends on the role of the user: + # + # # Assumes plan_id is accessible because it depends on the role. + # params[:account] = params[:account].except(:plan_id) unless admin? + # @account.update_attributes(params[:account]) + # + # Note that +attr_accessible+ is still applied to the received hash. Thus, + # with this technique you can at most _narrow_ the list of accessible + # attributes for a particular mass-assignment call. def attr_accessible(*attributes) write_inheritable_attribute(:attr_accessible, Set.new(attributes.map(&:to_s)) + (accessible_attributes || [])) end @@ -1382,14 +1418,14 @@ module ActiveRecord #:nodoc: classes rescue # OPTIMIZE this rescue is to fix this test: ./test/cases/reflection_test.rb:56:in `test_human_name_for_column' - # Appearantly the method base_class causes some trouble. + # Apparently the method base_class causes some trouble. # It now works for sure. [self] end # Transforms attribute key names into a more humane format, such as "First name" instead of "first_name". Example: # Person.human_attribute_name("first_name") # => "First name" - # This used to be depricated in favor of humanize, but is now preferred, because it automatically uses the I18n + # This used to be deprecated in favor of humanize, but is now preferred, because it automatically uses the I18n # module now. # Specify +options+ with additional translating options. def human_attribute_name(attribute_key_name, options = {}) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index 500dafdc2e..12253eac3f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -362,7 +362,7 @@ module ActiveRecord def call(env) @app.call(env) ensure - # Don't return connection (and peform implicit rollback) if + # Don't return connection (and perform implicit rollback) if # this request is a part of integration test unless env.key?("rack.test") ActiveRecord::Base.clear_active_connections! diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index f44cd0bd5a..2473c772e3 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -41,11 +41,19 @@ module ActiveRecord # # create_table() passes a TableDefinition object to the block. # # This form will not only create the table, but also columns for the # # table. + # # create_table(:suppliers) do |t| # t.column :name, :string, :limit => 60 # # Other fields here # end # + # === Block form, with shorthand + # # You can also use the column types as method calls, rather than calling the column method. + # create_table(:suppliers) do |t| + # t.string :name, :limit => 60 + # # Other fields here + # end + # # === Regular form # # Creates a table called 'suppliers' with no columns. # create_table(:suppliers) diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 2b0cfc2c3b..6eeeddc9e1 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -409,7 +409,7 @@ end # subdomain: $LABEL # # Also, sometimes (like when porting older join table fixtures) you'll need -# to be able to get ahold of the identifier for a given label. ERB +# to be able to get a hold of the identifier for a given label. ERB # to the rescue: # # george_reginald: diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index 0beb4321a2..bc4cca7855 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -284,7 +284,7 @@ module ActiveRecord # }) # # Will update the name of the Person with ID 1, build a new associated - # person with the name `John', and mark the associatied Person with ID 2 + # person with the name `John', and mark the associated Person with ID 2 # for destruction. # # Also accepts an Array of attribute hashes: diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 7ac6f6fe3b..a7fa98756e 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -63,7 +63,7 @@ module ActiveRecord # default message (e.g. <tt>activerecord.errors.messages.MESSAGE</tt>). The translated model name, # translated attribute name and the value are available for interpolation. # - # When using inheritence in your models, it will check all the inherited models too, but only if the model itself + # When using inheritance in your models, it will check all the inherited models too, but only if the model itself # hasn't been found. Say you have <tt>class Admin < User; end</tt> and you wanted the translation for the <tt>:blank</tt> # error +message+ for the <tt>title</tt> +attribute+, it looks for these translations: # |