Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/rails/rails
Browse files Browse the repository at this point in the history
  • Loading branch information
rizwanreza committed Jun 4, 2010
2 parents 1535b02 + 8e8cb17 commit e6f2102
Show file tree
Hide file tree
Showing 38 changed files with 173 additions and 64 deletions.
1 change: 1 addition & 0 deletions actionmailer/lib/action_mailer/base.rb
Expand Up @@ -311,6 +311,7 @@ class Base < AbstractController::Base
include AbstractController::Layouts
include AbstractController::Helpers
include AbstractController::Translation
include AbstractController::AssetPaths

helper ActionMailer::MailHelper

Expand Down
9 changes: 9 additions & 0 deletions actionmailer/lib/action_mailer/railtie.rb
Expand Up @@ -13,7 +13,16 @@ class Railtie < Rails::Railtie
end

initializer "action_mailer.set_configs" do |app|
paths = app.config.paths
am = app.config.action_mailer

am.assets_dir ||= paths.public.to_a.first
am.javascripts_dir ||= paths.public.javascripts.to_a.first
am.stylesheets_dir ||= paths.public.stylesheets.to_a.first

ActiveSupport.on_load(:action_mailer) do
self.config.merge!(am)

include app.routes.url_helpers

app.config.action_mailer.each do |k,v|
Expand Down
2 changes: 2 additions & 0 deletions actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.0.0 [beta 4/release candidate] (unreleased)*

* Remove middleware laziness [José Valim]

* Make session stores rely on request.cookie_jar and change set_session semantics to return the cookie value instead of a boolean. [José Valim]

* OAuth 2: HTTP Token Authorization support to complement Basic and Digest Authorization. [Rick Olson]
Expand Down
1 change: 1 addition & 0 deletions actionpack/lib/abstract_controller.rb
Expand Up @@ -20,5 +20,6 @@ module AbstractController
autoload :Logger
autoload :Rendering
autoload :Translation
autoload :AssetPaths
autoload :ViewPaths
end
9 changes: 9 additions & 0 deletions actionpack/lib/abstract_controller/asset_paths.rb
@@ -0,0 +1,9 @@
module AbstractController
module AssetPaths
extend ActiveSupport::Concern

included do
config_accessor :assets_dir, :javascripts_dir, :stylesheets_dir
end
end
end
1 change: 1 addition & 0 deletions actionpack/lib/abstract_controller/base.rb
@@ -1,4 +1,5 @@
require 'active_support/configurable'
require 'active_support/core_ext/module/anonymous'

module AbstractController
class Error < StandardError; end
Expand Down
1 change: 1 addition & 0 deletions actionpack/lib/abstract_controller/rendering.rb
@@ -1,4 +1,5 @@
require "abstract_controller/base"
require "action_view"

module AbstractController
class DoubleRenderError < Error
Expand Down
4 changes: 2 additions & 2 deletions actionpack/lib/action_controller/base.rb
Expand Up @@ -13,6 +13,7 @@ def self.without_modules(*modules)
MODULES = [
AbstractController::Layouts,
AbstractController::Translation,
AbstractController::AssetPaths,

Helpers,
HideActions,
Expand Down Expand Up @@ -66,8 +67,7 @@ def self.subclasses
@subclasses ||= []
end

# TODO Move this to the appropriate module
config_accessor :assets_dir, :asset_path, :javascripts_dir, :stylesheets_dir
config_accessor :asset_host, :asset_path

ActiveSupport.run_load_hooks(:action_controller, self)
end
Expand Down
8 changes: 4 additions & 4 deletions actionpack/lib/action_controller/metal/rack_delegation.rb
Expand Up @@ -8,10 +8,10 @@ module RackDelegation
delegate :headers, :status=, :location=, :content_type=,
:status, :location, :content_type, :to => "@_response"

def dispatch(action, request)
@_response = ActionDispatch::Response.new
@_response.request = request
super
def dispatch(action, request, response = ActionDispatch::Response.new)
@_response ||= response
@_response.request ||= request
super(action, request)
end

def params
Expand Down
Expand Up @@ -47,6 +47,7 @@ module RequestForgeryProtection
extend ActiveSupport::Concern

include AbstractController::Helpers
include AbstractController::Callbacks

included do
# Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
Expand Down
1 change: 1 addition & 0 deletions actionpack/lib/action_view/paths.rb
Expand Up @@ -31,6 +31,7 @@ def exists?(*args)

def typecast!
each_with_index do |path, i|
path = path.to_s if path.is_a?(Pathname)
next unless path.is_a?(String)
self[i] = FileSystemResolver.new(path)
end
Expand Down
Expand Up @@ -411,7 +411,8 @@ def method_missing(method, *args)
end
elsif @reflection.klass.scopes[method]
@_named_scopes_cache ||= {}
@_named_scopes_cache[method] ||= with_scope(construct_scope) { @reflection.klass.send(method, *args) }
@_named_scopes_cache[method] ||= {}
@_named_scopes_cache[method][args] ||= with_scope(construct_scope) { @reflection.klass.send(method, *args) }
else
with_scope(construct_scope) do
if block_given?
Expand Down
1 change: 1 addition & 0 deletions activerecord/lib/active_record/railties/databases.rake
Expand Up @@ -435,6 +435,7 @@ namespace :db do
task :create => :environment do
raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
require 'rails/generators'
Rails::Generators.configure!
require 'rails/generators/rails/session_migration/session_migration_generator'
Rails::Generators::SessionMigrationGenerator.start [ ENV["MIGRATION"] || "add_sessions_table" ]
end
Expand Down
15 changes: 14 additions & 1 deletion activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -9,7 +9,7 @@ module QueryMethods
(ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).each do |query_method|
attr_accessor :"#{query_method}_values"

next if [:where, :having].include?(query_method)
next if [:where, :having, :select].include?(query_method)
class_eval <<-CEVAL, __FILE__, __LINE__ + 1
def #{query_method}(*args, &block)
new_relation = clone
Expand All @@ -21,6 +21,19 @@ def #{query_method}(*args, &block)
CEVAL
end

class_eval <<-CEVAL, __FILE__, __LINE__ + 1
def select(*args, &block)
if block_given?
to_a.select(&block)
else
new_relation = clone
value = Array.wrap(args.flatten).reject {|x| x.blank? }
new_relation.select_values += value if value.present?
new_relation
end
end
CEVAL

[:where, :having].each do |query_method|
class_eval <<-CEVAL, __FILE__, __LINE__ + 1
def #{query_method}(*args, &block)
Expand Down
Expand Up @@ -17,7 +17,7 @@ def remember; self.class.remembered << self; end

module ClassMethods
def remembered; @@remembered ||= []; end
def random_element; @@remembered.random_element; end
def sample; @@remembered.sample; end
end
end

Expand Down Expand Up @@ -79,14 +79,14 @@ def generate_test_object_graphs
[Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!)
end
1.upto(NUM_SIMPLE_OBJS) do
PaintColor.create!(:non_poly_one_id => NonPolyOne.random_element.id)
PaintTexture.create!(:non_poly_two_id => NonPolyTwo.random_element.id)
PaintColor.create!(:non_poly_one_id => NonPolyOne.sample.id)
PaintTexture.create!(:non_poly_two_id => NonPolyTwo.sample.id)
end
1.upto(NUM_SHAPE_EXPRESSIONS) do
shape_type = [Circle, Square, Triangle].random_element
paint_type = [PaintColor, PaintTexture].random_element
ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.random_element.id,
:paint_type => paint_type.to_s, :paint_id => paint_type.random_element.id)
shape_type = [Circle, Square, Triangle].sample
paint_type = [PaintColor, PaintTexture].sample
ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.sample.id,
:paint_type => paint_type.to_s, :paint_id => paint_type.sample.id)
end
end

Expand Down
15 changes: 14 additions & 1 deletion activerecord/test/cases/named_scope_test.rb
Expand Up @@ -301,7 +301,7 @@ def test_find_all_should_behave_like_select
end

def test_rand_should_select_a_random_object_from_proxy
assert_kind_of Topic, Topic.approved.random_element
assert_kind_of Topic, Topic.approved.sample
end

def test_should_use_where_in_query_for_named_scope
Expand Down Expand Up @@ -428,6 +428,19 @@ def test_named_scopes_are_cached_on_associations
assert_no_queries { post.comments.containing_the_letter_e.all }
end

def test_named_scopes_with_arguments_are_cached_on_associations
post = posts(:welcome)

one = post.comments.limit_by(1).all
assert_equal 1, one.size

two = post.comments.limit_by(2).all
assert_equal 2, two.size

assert_no_queries { post.comments.limit_by(1).all }
assert_no_queries { post.comments.limit_by(2).all }
end

def test_named_scopes_are_reset_on_association_reload
post = posts(:welcome)

Expand Down
5 changes: 5 additions & 0 deletions activerecord/test/cases/relations_test.rb
Expand Up @@ -112,6 +112,11 @@ def test_finding_with_group
assert_equal 4, developers.map(&:salary).uniq.size
end

def test_select_with_block
even_ids = Developer.scoped.select {|d| d.id % 2 == 0 }.map(&:id)
assert_equal [2, 4, 6, 8, 10], even_ids
end

def test_finding_with_hash_conditions_on_joined_table
firms = DependentFirm.joins(:account).where({:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}).to_a
assert_equal 1, firms.size
Expand Down
1 change: 1 addition & 0 deletions activerecord/test/models/comment.rb
@@ -1,4 +1,5 @@
class Comment < ActiveRecord::Base
scope :limit_by, lambda {|l| limit(l) }
scope :containing_the_letter_e, :conditions => "comments.body LIKE '%e%'"
scope :for_first_post, :conditions => { :post_id => 1 }
scope :for_first_author,
Expand Down
2 changes: 1 addition & 1 deletion activesupport/CHANGELOG
Expand Up @@ -4,7 +4,7 @@

* Ruby 1.9: support UTF-8 case folding. #4595 [Norman Clarke]

* Renames Array#rand -> Array#random_element. [Santiago Pastorino, Rizwan Reza]
* Removes Array#rand and backports Array#sample from Ruby 1.9, thanks to Marc-Andre Lafortune. [fxn]

* Ruby 1.9: Renames last_(month|year) to prev_(month|year) in Date and Time. [fxn]

Expand Down
22 changes: 18 additions & 4 deletions activesupport/lib/active_support/core_ext/array/random_access.rb
@@ -1,6 +1,20 @@
class Array
# Returns a random element from the array.
def random_element
self[Kernel.rand(length)]
end
# Backport of Array#sample based on Marc-Andre Lafortune's http://github.com/marcandre/backports/
def sample(n=nil)
return self[Kernel.rand(size)] if n.nil?
n = n.to_int
rescue Exception => e
raise TypeError, "Coercion error: #{n.inspect}.to_int => Integer failed:\n(#{e.message})"
else
raise TypeError, "Coercion error: obj.to_int did NOT return an Integer (was #{n.class})" unless n.kind_of? Integer
raise ArgumentError, "negative array size" if n < 0
n = size if n > size
result = Array.new(self)
n.times do |i|
r = i + Kernel.rand(size - i)
result[i], result[r] = result[r], result[i]
end
result[n..size] = []
result
end unless method_defined? :sample
end
Expand Up @@ -2,7 +2,7 @@ module Kernel
unless respond_to?(:debugger)
# Starts a debugging session if ruby-debug has been loaded (call rails server --debugger to do load it).
def debugger
message = "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
message = "\n***** Debugger requested, but was not available (ensure ruby-debug is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
end
end
Expand Down
30 changes: 23 additions & 7 deletions activesupport/test/core_ext/array_ext_test.rb
Expand Up @@ -359,14 +359,30 @@ def test_uniq_by!
end

class ArrayExtRandomTests < ActiveSupport::TestCase
def test_random_element_from_array
assert_nil [].random_element

Kernel.expects(:rand).with(1).returns(0)
assert_equal 'x', ['x'].random_element
def test_sample_from_array
assert_nil [].sample
assert_equal [], [].sample(5)
assert_equal 42, [42].sample
assert_equal [42], [42].sample(5)

a = [:foo, :bar, 42]
s = a.sample(2)
assert_equal 2, s.size
assert_equal 1, (a-s).size
assert_equal [], a-(0..20).sum{a.sample(2)}

o = Object.new
def o.to_int; 1; end
assert_equal [0], [0].sample(o)

o = Object.new
assert_raises(TypeError) { [0].sample(o) }

o = Object.new
def o.to_int; ''; end
assert_raises(TypeError) { [0].sample(o) }

Kernel.expects(:rand).with(3).returns(1)
assert_equal 2, [1, 2, 3].random_element
assert_raises(ArgumentError) { [0].sample(-7) }
end
end

Expand Down
2 changes: 1 addition & 1 deletion railties/CHANGELOG
@@ -1,7 +1,7 @@
*Rails 3.0.0 [beta 4/release candidate] (unreleased)*

* Version bump

* Removed Rails Metal [YK & JV].

*Rails 3.0.0 [beta 3] (April 13th, 2010)*

Expand Down
7 changes: 4 additions & 3 deletions railties/guides/source/3_0_release_notes.textile
Expand Up @@ -81,7 +81,7 @@ The new installing rails sequence (for the beta) is:

<shell>
$ gem install rails --prerelease
$ rails myapp
$ rails new myapp
$ cd myapp
</shell>

Expand All @@ -98,13 +98,13 @@ h4. Living on the Edge
If you want to bundle straight from the Git repository, you can pass the +--edge+ flag:

<shell>
$ rails myapp --edge
$ rails new myapp --edge
</shell>

If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the +--dev+ flag:

<shell>
$ ruby /path/to/rails/bin/rails myapp --dev
$ ruby /path/to/rails/bin/rails new myapp --dev
</shell>

h3. Rails Architectural Changes
Expand Down Expand Up @@ -512,6 +512,7 @@ These are the main changes in Active Support:
* Active Support no longer provides vendored versions of "TZInfo":http://tzinfo.rubyforge.org/, "Memcache Client":http://deveiate.org/projects/RMemCache/ and "Builder":http://builder.rubyforge.org/, these are all included as dependencies and installed via the <tt>bundle install</tt> command.
* Safe buffers are implemented in <tt>ActiveSupport::SafeBuffer</tt>.
* Added <tt>Array.uniq_by</tt> and <tt>Array.uniq_by!</tt>.
* Removed <tt>Array#rand</tt> and backported <tt>Array#sample</tt> from Ruby 1.9.
* Fixed bug on +TimeZone.seconds_to_utc_offset+ returning wrong value.
* Added <tt>ActiveSupport::Notifications</tt> middleware.
* <tt>ActiveSupport.use_standard_json_time_format</tt> now defaults to true.
Expand Down
14 changes: 11 additions & 3 deletions railties/guides/source/active_support_core_extensions.textile
Expand Up @@ -1927,13 +1927,21 @@ 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 builtin). Thanks to social wisdom and positive constructiveness all around, +forty_two+ is also available.

You can pick a random element with +random_element+:
NOTE: Defined in +active_support/core_ext/array/access.rb+.

h4. Random Access

Active Support backports +sample+ from Ruby 1.9:

<ruby>
shape_type = [Circle, Square, Triangle].random_element
shape_type = [Circle, Square, Triangle].sample
# => Square, for example

shape_types = [Circle, Square, Triangle].sample(2)
# => [Triangle, Circle], for example
</ruby>

NOTE: Defined in +active_support/core_ext/array/access.rb+.
NOTE: Defined in +active_support/core_ext/array/random_access.rb+.

h4. Options Extraction

Expand Down

0 comments on commit e6f2102

Please sign in to comment.