diff options
Diffstat (limited to 'railties/guides/source')
6 files changed, 64 insertions, 22 deletions
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index 7cdffe4c2e..2f0a51e868 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -418,7 +418,7 @@ SELECT viewable_by, locked FROM clients Be careful because this also means you're initializing a model object with only the fields that you've selected. If you attempt to access a field that is not in the initialized record you'll receive: <shell> -ActiveRecord::MissingAttributeError: missing attribute: <attribute> +ActiveModel::MissingAttributeError: missing attribute: <attribute> </shell> Where +<attribute>+ is the attribute you asked for. The +id+ method will not raise the +ActiveRecord::MissingAttributeError+, so just be careful when working with associations because they need the +id+ method to function properly. diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile index 9aab4b6694..19bd4ad0f1 100644 --- a/railties/guides/source/active_record_validations_callbacks.textile +++ b/railties/guides/source/active_record_validations_callbacks.textile @@ -897,8 +897,9 @@ The macro-style class methods can also receive a block. Consider using this styl class User < ActiveRecord::Base validates_presence_of :login, :email - before_create {|user| user.name = user.login.capitalize - if user.name.blank?} + before_create do |user| + user.name = user.login.capitalize if user.name.blank? + end end </ruby> diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index b7f842a0d0..f89c83e4cd 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1266,6 +1266,15 @@ WARNING: The option +:separator+ can't be a regexp. NOTE: Defined in +active_support/core_ext/string/filters.rb+. +h4. +inquiry+ + +The <tt>inquiry</tt> method converts a string into a +StringInquirer+ object making equality checks prettier. + +<ruby> +"production".inquiry.production? # => true +"active".inquiry.inactive? # => false +</ruby> + h4. Key-based Interpolation In Ruby 1.9 the <tt>%</tt> string operator supports key-based interpolation, both formatted and unformatted: @@ -1997,6 +2006,11 @@ Similarly, +from+ returns the tail from the element at the passed index on: The methods +second+, +third+, +fourth+, and +fifth+ return the corresponding element (+first+ is built-in). Thanks to social wisdom and positive constructiveness all around, +forty_two+ is also available. +<ruby> +%w(a b c d).third # => c +%w(a b c d).fifth # => nil +</ruby> + NOTE: Defined in +active_support/core_ext/array/access.rb+. h4. Random Access @@ -2092,7 +2106,7 @@ h5. +to_xml+ The method +to_xml+ returns a string containing an XML representation of its receiver: <ruby> -Contributor.all(:limit => 2, :order => 'rank ASC').to_xml +Contributor.limit(2).order(:rank).to_xml # => # <?xml version="1.0" encoding="UTF-8"?> # <contributors type="array"> @@ -2167,7 +2181,7 @@ The name of children nodes is by default the name of the root node singularized. The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You can configure your own builder via the <tt>:builder</tt> option. The method also accepts options like <tt>:dasherize</tt> and friends, they are forwarded to the builder: <ruby> -Contributor.all(:limit => 2, :order => 'rank ASC').to_xml(:skip_types => true) +Contributor.limit(2).order(:rank).to_xml(:skip_types => true) # => # <?xml version="1.0" encoding="UTF-8"?> # <contributors> @@ -3407,11 +3421,11 @@ h4. +silence+ Silences every log level lesser to the specified one for the duration of the given block. Log level orders are: debug, info, error and fatal. <ruby> - logger = Logger.new("log/development.log") - logger.silence(Logger::INFO) do - logger.debug("In space, no one can hear you scream.") - logger.info("Scream all you want, small mailman!") - end +logger = Logger.new("log/development.log") +logger.silence(Logger::INFO) do + logger.debug("In space, no one can hear you scream.") + logger.info("Scream all you want, small mailman!") +end </ruby> h4. +datetime_format=+ @@ -3419,17 +3433,17 @@ h4. +datetime_format=+ Modifies the datetime format output by the formatter class associated with this logger. If the formatter class does not have a +datetime_format+ method then this is ignored. <ruby> - class Logger::FormatWithTime < Logger::Formatter - cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" } +class Logger::FormatWithTime < Logger::Formatter + cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" } - def self.call(severity, timestamp, progname, msg) - "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n" - end + def self.call(severity, timestamp, progname, msg) + "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n" end +end - logger = Logger.new("log/development.log") - logger.formatter = Logger::FormatWithTime - logger.info("<- is the current time") +logger = Logger.new("log/development.log") +logger.formatter = Logger::FormatWithTime +logger.info("<- is the current time") </ruby> NOTE: Defined in +active_support/core_ext/logger.rb+. diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index 53460b8c36..d7069b31fc 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -229,6 +229,8 @@ h4. Configuring Active Record * +config.active_record.lock_optimistically+ controls whether ActiveRecord will use optimistic locking. By default this is +true+. +* +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app. + The MySQL adapter adds one additional configuration option: * +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether ActiveRecord will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+. diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index 95b877aecf..43c08165dc 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -557,7 +557,7 @@ match '*a/foo/*b' => 'test#index' would match +zoo/woo/foo/bar/baz+ with +params[:a]+ equals +"zoo/woo"+, and +params[:b]+ equals +"bar/baz"+. -NOTE: Starting from Rails 3.1, wildcard route will always matching the optional format segment by default. For example if you have this route: +NOTE: Starting from Rails 3.1, wildcard routes will always match the optional format segment by default. For example if you have this route: <ruby> map '*pages' => 'pages#show' diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index f4c1bde5b1..f87ffdb20d 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -418,10 +418,17 @@ To avoid this, Rails provides two class methods in your Active Record class to c attr_protected :admin </ruby> ++attr_protected+ also optionally takes a scope option using :as which allows you to define multiple mass-assignment groupings. If no scope is defined then attributes will be added to the default group. + +<ruby> +attr_protected :last_login, :as => :admin +</ruby> + A much better way, because it follows the whitelist-principle, is the +attr_accessible+ method. It is the exact opposite of +attr_protected+, because _(highlight)it takes a list of attributes that will be accessible_. All other attributes will be protected. This way you won't forget to protect attributes when adding new ones in the course of development. Here is an example: <ruby> attr_accessible :name +attr_accessible :name, :is_admin, :as => :admin </ruby> If you want to set a protected attribute, you will to have to assign it individually: @@ -434,13 +441,31 @@ params[:user] # => {:name => "ow3ned", :admin => true} @user.admin # => true </ruby> -A more paranoid technique to protect your whole project would be to enforce that all models whitelist their accessible attributes. This can be easily achieved with a very simple initializer: +When assigning attributes in Active Record using +new+, +attributes=+, or +update_attributes+ the :default scope will be used. To assign attributes using different scopes you should use +assign_attributes+ which accepts an optional :as options parameter. If no :as option is provided then the :default scope will be used. You can also bypass mass-assignment security by using the +:without_protection+ option. Here is an example: + +<ruby> +@user = User.new + +@user.assign_attributes({ :name => 'Josh', :is_admin => true }) +@user.name # => Josh +@user.is_admin # => false + +@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :as => :admin) +@user.name # => Josh +@user.is_admin # => true + +@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true) +@user.name # => Josh +@user.is_admin # => true +</ruby> + +A more paranoid technique to protect your whole project would be to enforce that all models define their accessible attributes. This can be easily achieved with a very simple application config option of: <ruby> -ActiveRecord::Base.send(:attr_accessible, nil) +config.active_record.whitelist_attributes = true </ruby> -This will create an empty whitelist of attributes available for mass assignment for all models in your app. As such, your models will need to explicitly whitelist accessible parameters by using an +attr_accessible+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to insert this initializer, run your tests, and expose each attribute (via +attr_accessible+) as dictated by your failing tests. +This will create an empty whitelist of attributes available for mass-assignment for all models in your app. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an +attr_accessible+ or +attr_protected+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to use this application config option; run your tests, and expose each attribute (via +attr_accessible+ or +attr_protected+) as dictated by your failing tests. h3. User Management |