diff options
-rw-r--r-- | activemodel/test/cases/railtie_test.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 83 | ||||
-rw-r--r-- | guides/source/active_record_validations.md | 5 | ||||
-rw-r--r-- | guides/source/getting_started.md | 15 | ||||
-rw-r--r-- | guides/source/security.md | 2 | ||||
-rw-r--r-- | railties/CHANGELOG.md | 4 | ||||
-rw-r--r-- | railties/lib/rails/application/bootstrap.rb | 3 | ||||
-rw-r--r-- | railties/test/application/configuration_test.rb | 8 |
8 files changed, 78 insertions, 44 deletions
diff --git a/activemodel/test/cases/railtie_test.rb b/activemodel/test/cases/railtie_test.rb index 0643fa775d..96b3b07e50 100644 --- a/activemodel/test/cases/railtie_test.rb +++ b/activemodel/test/cases/railtie_test.rb @@ -8,7 +8,7 @@ class RailtieTest < ActiveModel::TestCase require 'active_model/railtie' # Set a fake logger to avoid creating the log directory automatically - fake_logger = mock() + fake_logger = Logger.new(nil) @app ||= Class.new(::Rails::Application) do config.eager_load = false diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 49b632c4c7..9f2a039d94 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -119,14 +119,15 @@ module ActiveRecord # # User.includes(:posts).where('posts.name = ?', 'example').references(:posts) def includes(*args) - check_if_method_has_arguments!("includes", args) + check_if_method_has_arguments!(:includes, args) spawn.includes!(*args) end def includes!(*args) # :nodoc: - args.reject! {|a| a.blank? } + args.reject!(&:blank?) + args.flatten! - self.includes_values = (includes_values + args).flatten.uniq + self.includes_values |= args self end @@ -137,7 +138,7 @@ module ActiveRecord # FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = # "users"."id" def eager_load(*args) - check_if_method_has_arguments!("eager_load", args) + check_if_method_has_arguments!(:eager_load, args) spawn.eager_load!(*args) end @@ -151,7 +152,7 @@ module ActiveRecord # User.preload(:posts) # => SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3) def preload(*args) - check_if_method_has_arguments!("preload", args) + check_if_method_has_arguments!(:preload, args) spawn.preload!(*args) end @@ -169,14 +170,15 @@ module ActiveRecord # User.includes(:posts).where("posts.name = 'foo'").references(:posts) # # => Query now knows the string references posts, so adds a JOIN def references(*args) - check_if_method_has_arguments!("references", args) + check_if_method_has_arguments!(:references, args) spawn.references!(*args) end def references!(*args) # :nodoc: args.flatten! + args.map!(&:to_s) - self.references_values = (references_values + args.map!(&:to_s)).uniq + self.references_values |= args self end @@ -229,7 +231,9 @@ module ActiveRecord end def select!(*fields) # :nodoc: - self.select_values += fields.flatten + fields.flatten! + + self.select_values += fields self end @@ -249,7 +253,7 @@ module ActiveRecord # User.group('name AS grouped_name, age') # => [#<User id: 3, name: "Foo", age: 21, ...>, #<User id: 2, name: "Oscar", age: 21, ...>, #<User id: 5, name: "Foo", age: 23, ...>] def group(*args) - check_if_method_has_arguments!("group", args) + check_if_method_has_arguments!(:group, args) spawn.group!(*args) end @@ -280,24 +284,22 @@ module ActiveRecord # User.order(:name, email: :desc) # => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC def order(*args) - check_if_method_has_arguments!("order", args) + check_if_method_has_arguments!(:order, args) spawn.order!(*args) end def order!(*args) # :nodoc: args.flatten! - validate_order_args args + validate_order_args(args) references = args.grep(String) references.map! { |arg| arg =~ /^([a-zA-Z]\w*)\.(\w+)/ && $1 }.compact! references!(references) if references.any? # if a symbol is given we prepend the quoted table name - args.map! { |arg| - arg.is_a?(Symbol) ? - Arel::Nodes::Ascending.new(klass.arel_table[arg]) : - arg - } + args.map! do |arg| + arg.is_a?(Symbol) ? Arel::Nodes::Ascending.new(klass.arel_table[arg]) : arg + end self.order_values += args self @@ -313,13 +315,13 @@ module ActiveRecord # # generates a query with 'ORDER BY id ASC, name ASC'. def reorder(*args) - check_if_method_has_arguments!("reorder", args) + check_if_method_has_arguments!(:reorder, args) spawn.reorder!(*args) end def reorder!(*args) # :nodoc: args.flatten! - validate_order_args args + validate_order_args(args) self.reordering_value = true self.order_values = args @@ -361,7 +363,7 @@ module ActiveRecord # # will still have an order if it comes from the default_scope on Comment. def unscope(*args) - check_if_method_has_arguments!("unscope", args) + check_if_method_has_arguments!(:unscope, args) spawn.unscope!(*args) end @@ -400,8 +402,12 @@ module ActiveRecord # User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id") # => SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id def joins(*args) - check_if_method_has_arguments!("joins", args) - spawn.joins!(*args.compact.flatten) + check_if_method_has_arguments!(:joins, args) + + args.compact! + args.flatten! + + spawn.joins!(*args) end def joins!(*args) # :nodoc: @@ -783,9 +789,10 @@ module ActiveRecord end def extending!(*modules, &block) # :nodoc: - modules << Module.new(&block) if block_given? + modules << Module.new(&block) if block + modules.flatten! - self.extending_values += modules.flatten + self.extending_values += modules extend(*extending_values) if extending_values.any? self @@ -816,12 +823,12 @@ module ActiveRecord collapse_wheres(arel, (where_values - ['']).uniq) - arel.having(*having_values.uniq.reject{|h| h.blank?}) unless having_values.empty? + arel.having(*having_values.uniq.reject(&:blank?)) unless having_values.empty? arel.take(connection.sanitize_limit(limit_value)) if limit_value arel.skip(offset_value.to_i) if offset_value - arel.group(*group_values.uniq.reject{|g| g.blank?}) unless group_values.empty? + arel.group(*group_values.uniq.reject(&:blank?)) unless group_values.empty? build_order(arel) @@ -870,11 +877,11 @@ module ActiveRecord end def custom_join_ast(table, joins) - joins = joins.reject { |join| join.blank? } + joins = joins.reject(&:blank?) return [] if joins.empty? - joins.map do |join| + joins.map! do |join| case join when Array join = Arel.sql(join.join(' ')) if array_of_strings?(join) @@ -901,7 +908,7 @@ module ActiveRecord when String, Array [@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))] when Hash - opts = PredicateBuilder.resolve_column_aliases klass, opts + opts = PredicateBuilder.resolve_column_aliases(klass, opts) attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts) attributes.values.grep(ActiveRecord::Relation) do |rel| @@ -944,7 +951,7 @@ module ActiveRecord association_joins = buckets[:association_join] || [] stashed_association_joins = buckets[:stashed_join] || [] join_nodes = (buckets[:join_node] || []).uniq - string_joins = (buckets[:string_join] || []).map { |x| x.strip }.uniq + string_joins = (buckets[:string_join] || []).map(&:strip).uniq join_list = join_nodes + custom_join_ast(manager, string_joins) @@ -956,13 +963,12 @@ module ActiveRecord join_dependency.graft(*stashed_association_joins) - joins = join_dependency.join_associations.map { |association| - association.join_constraints - }.flatten + joins = join_dependency.join_associations.map!(&:join_constraints) + joins.flatten! - joins.each { |join| manager.from join } + joins.each { |join| manager.from(join) } - manager.join_sources.concat join_list + manager.join_sources.concat(join_list) manager end @@ -983,7 +989,7 @@ module ActiveRecord when Arel::Nodes::Ordering o.reverse when String - o.to_s.split(',').collect do |s| + o.to_s.split(',').map! do |s| s.strip! s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC') end @@ -1000,14 +1006,15 @@ module ActiveRecord end def array_of_strings?(o) - o.is_a?(Array) && o.all?{|obj| obj.is_a?(String)} + o.is_a?(Array) && o.all? { |obj| obj.is_a?(String) } end def build_order(arel) - orders = order_values + orders = order_values.uniq + orders.reject!(&:blank?) orders = reverse_sql_order(orders) if reverse_order_value - orders = orders.uniq.reject(&:blank?).flat_map do |order| + orders = orders.flat_map do |order| case order when Symbol table[order].asc diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md index d95b587e78..8154d4e1cc 100644 --- a/guides/source/active_record_validations.md +++ b/guides/source/active_record_validations.md @@ -243,7 +243,7 @@ line of code you can add the same kind of validation to several attributes. All of them accept the `:on` and `:message` options, which define when the validation should be run and what message should be added to the `errors` collection if it fails, respectively. The `:on` option takes one of the values -`:save` (the default), `:create` or `:update`. There is a default error +`:create` or `:update`. There is a default error message for each one of the validation helpers. These messages are used when the `:message` option isn't specified. Let's take a look at each one of the available helpers. @@ -765,10 +765,9 @@ class Person < ActiveRecord::Base validates :age, numericality: true, on: :update # the default (validates on both create and update) - validates :name, presence: true, on: :save + validates :name, presence: true end ``` -The last line is in review state and as of now, it is not running in any version of Rails 3.2.x as discussed in this [issue](https://github.com/rails/rails/issues/10248) Strict Validations ------------------ diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 20d7eb3381..12eb88f018 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -1616,6 +1616,8 @@ end Security -------- +### Basic Authentication + If you were to publish your blog online, anybody would be able to add, edit and delete posts or delete comments. @@ -1663,6 +1665,19 @@ Authentication challenge  +Other authentication methods are available for Rails applications. Two popular +authentication add-ons for Rails are the [Devise](https://github.com/plataformatec/devise) +rails engine and the [Authlogic](https://github.com/binarylogic/authlogic) gem, +along with a number of others. + + +### Other Security Considerations + +Security, especially in web applications, is a broad and detailed area. Security +in your Rails application is covered in more depth in +The [Ruby on Rails Security Guide](security.html) + + What's Next? ------------ diff --git a/guides/source/security.md b/guides/source/security.md index ad0546810d..e4db26c64e 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -93,7 +93,7 @@ Rails 2 introduced a new default session storage, CookieStore. CookieStore saves * The client can see everything you store in a session, because it is stored in clear-text (actually Base64-encoded, so not encrypted). So, of course, _you don't want to store any secrets here_. To prevent session hash tampering, a digest is calculated from the session with a server-side secret and inserted into the end of the cookie. -That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA512, which has not been compromised, yet). So _don't use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters_. +That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA1, for compatibility). So _don't use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters_. `config.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `config.secret_key_base` initialized to a random key in `config/initializers/secret_token.rb`, e.g.: diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 30328a0c19..1965d09297 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,7 @@ +* Make `config.log_level` work with custom loggers. + + *Max Shytikov* + * Changed stylesheet load order in the stylesheet manifest generator. Fixes #11639. diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index 62d57c0cc6..a26d41c0cf 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -42,7 +42,6 @@ INFO logger = ActiveSupport::Logger.new f logger.formatter = config.log_formatter logger = ActiveSupport::TaggedLogging.new(logger) - logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase) logger rescue StandardError logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDERR)) @@ -53,6 +52,8 @@ INFO ) logger end + + Rails.logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase) end # Initialize cache early in the stack so railties can make use of it. diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 28839a9c4b..c51488e0e1 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -671,5 +671,13 @@ module ApplicationTests end end end + + test "config.log_level with custom logger" do + make_basic_app do |app| + app.config.logger = Logger.new(STDOUT) + app.config.log_level = :info + end + assert_equal Logger::INFO, Rails.logger.level + end end end |