Skip to content

Commit 26c5680

Browse files
committed
Merge branch 'master' of github.com:rails/rails
2 parents b870dab + 4b91daf commit 26c5680

File tree

41 files changed

+316
-104
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+316
-104
lines changed

Gemfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ elsif RUBY_ENGINE == "jruby"
2121
gem "jruby-openssl"
2222
end
2323

24+
# AS
25+
gem "memcache-client", ">= 1.7.5"
26+
27+
# AM
28+
gem "text-format", "~> 1.0.0"
29+
2430
# AR
2531
if mri || RUBY_ENGINE == "rbx"
2632
gem "sqlite3-ruby", "= 1.3.0.beta.2", :require => 'sqlite3'
@@ -39,7 +45,6 @@ elsif RUBY_ENGINE == "jruby"
3945
end
4046

4147
# AP
42-
gem "rack-test", "0.5.3", :require => 'rack/test'
4348
gem "RedCloth", ">= 4.2.2"
4449

4550
group :documentation do

actionmailer/actionmailer.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,4 @@ Gem::Specification.new do |s|
2121

2222
s.add_dependency('actionpack', version)
2323
s.add_dependency('mail', '~> 2.2.1')
24-
s.add_dependency('text-format', '~> 1.0.0')
2524
end

actionmailer/lib/action_mailer.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,3 @@ module ActionMailer
4949
autoload :TestCase
5050
autoload :TestHelper
5151
end
52-
53-
module Text
54-
extend ActiveSupport::Autoload
55-
56-
autoload :Format, 'text/format'
57-
end

actionmailer/lib/action_mailer/mail_helper.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ module MailHelper
33
# Uses Text::Format to take the text and format it, indented two spaces for
44
# each line, and wrapped at 72 columns.
55
def block_format(text)
6+
begin
7+
require 'text/format'
8+
rescue LoadError => e
9+
$stderr.puts "You don't have text-format installed in your application. Please add it to your Gemfile and run bundle install"
10+
raise e
11+
end unless defined?(Text::Format)
12+
613
formatted = text.split(/\n\r\n/).collect { |paragraph|
714
Text::Format.new(
815
:columns => 72, :first_indent => 2, :body_indent => 2, :text => paragraph

actionpack/actionpack.gemspec

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ Gem::Specification.new do |s|
2121

2222
s.add_dependency('activesupport', version)
2323
s.add_dependency('activemodel', version)
24+
s.add_dependency('builder', '~> 2.1.2')
25+
s.add_dependency('i18n', '~> 0.4.0')
2426
s.add_dependency('rack', '~> 1.1.0')
25-
s.add_dependency('rack-test', '~> 0.5.0')
27+
s.add_dependency('rack-test', '~> 0.5.4')
2628
s.add_dependency('rack-mount', '~> 0.6.3')
29+
s.add_dependency('tzinfo', '~> 0.3.16')
2730
s.add_dependency('erubis', '~> 2.6.5')
2831
end

actionpack/lib/action_controller/metal.rb

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,48 @@
11
require 'active_support/core_ext/class/attribute'
2+
require 'active_support/core_ext/object/blank'
3+
require 'action_dispatch/middleware/stack'
24

35
module ActionController
6+
# Extend ActionDispatch middleware stack to make it aware of options
7+
# allowing the following syntax in controllers:
8+
#
9+
# class PostsController < ApplicationController
10+
# use AuthenticationMiddleware, :except => [:index, :show]
11+
# end
12+
#
13+
class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
14+
class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
15+
def initialize(klass, *args)
16+
options = args.extract_options!
17+
@only = Array(options.delete(:only)).map(&:to_s)
18+
@except = Array(options.delete(:except)).map(&:to_s)
19+
args << options unless options.empty?
20+
super
21+
end
22+
23+
def valid?(action)
24+
if @only.present?
25+
@only.include?(action)
26+
elsif @except.present?
27+
!@except.include?(action)
28+
else
29+
true
30+
end
31+
end
32+
end
33+
34+
def build(action, app=nil, &block)
35+
app ||= block
36+
action = action.to_s
37+
raise "MiddlewareStack#build requires an app" unless app
38+
39+
reverse.inject(app) do |a, middleware|
40+
middleware.valid?(action) ?
41+
middleware.build(a) : a
42+
end
43+
end
44+
end
45+
446
# ActionController::Metal provides a way to get a valid Rack application from a controller.
547
#
648
# In AbstractController, dispatching is triggered directly by calling #process on a new controller.
@@ -91,10 +133,10 @@ def to_a
91133
end
92134

93135
class_attribute :middleware_stack
94-
self.middleware_stack = ActionDispatch::MiddlewareStack.new
136+
self.middleware_stack = ActionController::MiddlewareStack.new
95137

96138
def self.inherited(base)
97-
self.middleware_stack = base.middleware_stack.dup
139+
base.middleware_stack = self.middleware_stack.dup
98140
super
99141
end
100142

@@ -120,7 +162,7 @@ def self.call(env)
120162
# ==== Returns
121163
# Proc:: A rack application
122164
def self.action(name, klass = ActionDispatch::Request)
123-
middleware_stack.build do |env|
165+
middleware_stack.build(name.to_s) do |env|
124166
new.dispatch(name, klass.new(env))
125167
end
126168
end

actionpack/lib/action_dispatch/middleware/stack.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def initialize(*args, &block)
5555

5656
def insert(index, *args, &block)
5757
index = self.index(index) unless index.is_a?(Integer)
58-
middleware = Middleware.new(*args, &block)
58+
middleware = self.class::Middleware.new(*args, &block)
5959
super(index, middleware)
6060
end
6161

@@ -73,7 +73,7 @@ def swap(target, *args, &block)
7373
end
7474

7575
def use(*args, &block)
76-
middleware = Middleware.new(*args, &block)
76+
middleware = self.class::Middleware.new(*args, &block)
7777
push(middleware)
7878
end
7979

@@ -82,8 +82,8 @@ def active
8282
"was removed from the middleware stack", caller
8383
end
8484

85-
def build(app = nil, &blk)
86-
app ||= blk
85+
def build(app = nil, &block)
86+
app ||= block
8787
raise "MiddlewareStack#build requires an app" unless app
8888
reverse.inject(app) { |a, e| e.build(a) }
8989
end

actionpack/lib/action_view/base.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ module Subclasses
165165
cattr_accessor :debug_rjs
166166
@@debug_rjs = false
167167

168+
# Specify the proc used to decorate input tags that refer to attributes with errors.
169+
cattr_accessor :field_error_proc
170+
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
171+
168172
class_attribute :helpers
169173
remove_method :helpers
170174
attr_reader :helpers

actionpack/lib/action_view/helpers/active_model_helper.rb

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44
require 'active_support/core_ext/object/blank'
55

66
module ActionView
7-
ActiveSupport.on_load(:action_view) do
8-
class ActionView::Base
9-
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
10-
cattr_accessor :field_error_proc
11-
end
12-
end
13-
147
module Helpers
158
module ActiveModelHelper
169
%w(input form error_messages_for error_message_on).each do |method|

actionpack/lib/action_view/helpers/text_helper.rb

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'active_support/core_ext/object/blank'
2+
require 'active_support/core_ext/string/filters'
23
require 'action_view/helpers/tag_helper'
34

45
module ActionView
@@ -42,28 +43,25 @@ def safe_concat(string)
4243
# ==== Examples
4344
#
4445
# truncate("Once upon a time in a world far far away")
45-
# # => Once upon a time in a world...
46+
# # => "Once upon a time in a world..."
4647
#
47-
# truncate("Once upon a time in a world far far away", :separator => ' ')
48-
# # => Once upon a time in a world...
48+
# truncate("Once upon a time in a world far far away", :length => 17)
49+
# # => "Once upon a ti..."
4950
#
50-
# truncate("Once upon a time in a world far far away", :length => 14)
51-
# # => Once upon a...
51+
# truncate("Once upon a time in a world far far away", :lenght => 17, :separator => ' ')
52+
# # => "Once upon a..."
5253
#
53-
# truncate("And they found that many people were sleeping better.", :length => 25, "(clipped)")
54-
# # => And they found t(clipped)
55-
#
56-
# truncate("And they found that many people were sleeping better.", :omission => "... (continued)", :length => 25)
57-
# # => And they f... (continued)
54+
# truncate("And they found that many people were sleeping better.", :length => 25, :omission => '... (continued)')
55+
# # => "And they f... (continued)"
5856
#
5957
# You can still use <tt>truncate</tt> with the old API that accepts the
6058
# +length+ as its optional second and the +ellipsis+ as its
6159
# optional third parameter:
6260
# truncate("Once upon a time in a world far far away", 14)
63-
# # => Once upon a...
61+
# # => "Once upon a..."
6462
#
6563
# truncate("And they found that many people were sleeping better.", 25, "... (continued)")
66-
# # => And they f... (continued)
64+
# # => "And they f... (continued)"
6765
def truncate(text, *args)
6866
options = args.extract_options!
6967
unless args.empty?
@@ -73,14 +71,10 @@ def truncate(text, *args)
7371
options[:length] = args[0] || 30
7472
options[:omission] = args[1] || "..."
7573
end
76-
options.reverse_merge!(:length => 30, :omission => "...")
7774

78-
if text
79-
l = options[:length] - options[:omission].mb_chars.length
80-
chars = text.mb_chars
81-
stop = options[:separator] ? (chars.rindex(options[:separator].mb_chars, l) || l) : l
82-
(chars.length > options[:length] ? chars[0...stop] + options[:omission] : text).to_s
83-
end
75+
options.reverse_merge!(:length => 30)
76+
77+
text.truncate(options.delete(:length), options) if text
8478
end
8579

8680
# Highlights one or more +phrases+ everywhere in +text+ by inserting it into

actionpack/test/controller/new_base/middleware_test.rb

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ def call(env)
2828

2929
class MyController < ActionController::Metal
3030
use MyMiddleware
31-
3231
middleware.insert_before MyMiddleware, ExclaimerMiddleware
3332

3433
def index
@@ -39,8 +38,23 @@ def index
3938
class InheritedController < MyController
4039
end
4140

42-
module MiddlewareTests
43-
extend ActiveSupport::Testing::Declarative
41+
class ActionsController < ActionController::Metal
42+
use MyMiddleware, :only => :show
43+
middleware.insert_before MyMiddleware, ExclaimerMiddleware, :except => :index
44+
45+
def index
46+
self.response_body = "index"
47+
end
48+
49+
def show
50+
self.response_body = "show"
51+
end
52+
end
53+
54+
class TestMiddleware < ActiveSupport::TestCase
55+
def setup
56+
@app = MyController.action(:index)
57+
end
4458

4559
test "middleware that is 'use'd is called as part of the Rack application" do
4660
result = @app.call(env_for("/"))
@@ -52,13 +66,13 @@ module MiddlewareTests
5266
result = @app.call(env_for("/"))
5367
assert_equal "First!", result[1]["Middleware-Order"]
5468
end
55-
end
5669

57-
class TestMiddleware < ActiveSupport::TestCase
58-
include MiddlewareTests
70+
test "middleware stack accepts only and except as options" do
71+
result = ActionsController.action(:show).call(env_for("/"))
72+
assert_equal "First!", result[1]["Middleware-Order"]
5973

60-
def setup
61-
@app = MyController.action(:index)
74+
result = ActionsController.action(:index).call(env_for("/"))
75+
assert_nil result[1]["Middleware-Order"]
6276
end
6377

6478
def env_for(url)
@@ -70,8 +84,5 @@ class TestInheritedMiddleware < TestMiddleware
7084
def setup
7185
@app = InheritedController.action(:index)
7286
end
73-
74-
test "middleware inherits" do
75-
end
7687
end
7788
end

activemodel/activemodel.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ Gem::Specification.new do |s|
2020
s.has_rdoc = true
2121

2222
s.add_dependency('activesupport', version)
23+
s.add_dependency('builder', '~> 2.1.2')
24+
s.add_dependency('i18n', '~> 0.4.0')
2325
end

activemodel/lib/active_model/errors.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,13 @@ def to_xml(options={})
170170
end
171171
end
172172

173-
# Adds an error message (+messsage+) to the +attribute+, which will be returned on a call to <tt>on(attribute)</tt>
174-
# for the same attribute and ensure that this error object returns false when asked if <tt>empty?</tt>. More than one
175-
# error can be added to the same +attribute+ in which case an array will be returned on a call to <tt>on(attribute)</tt>.
176-
# If no +messsage+ is supplied, :invalid is assumed.
173+
# Adds +message+ to the error messages on +attribute+, which will be returned on a call to
174+
# <tt>on(attribute)</tt> for the same attribute. More than one error can be added to the same
175+
# +attribute+ in which case an array will be returned on a call to <tt>on(attribute)</tt>.
176+
# If no +message+ is supplied, <tt>:invalid</tt> is assumed.
177177
#
178-
# If +message+ is a Symbol, it will be translated, using the appropriate scope (see translate_error).
179-
# If +message+ is a Proc, it will be called, allowing for things like Time.now to be used within an error
178+
# If +message+ is a symbol, it will be translated using the appropriate scope (see +translate_error+).
179+
# If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error.
180180
def add(attribute, message = nil, options = {})
181181
message ||= :invalid
182182
message = generate_message(attribute, message, options) if message.is_a?(Symbol)

activerecord/activerecord.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ Gem::Specification.new do |s|
2424
s.add_dependency('activesupport', version)
2525
s.add_dependency('activemodel', version)
2626
s.add_dependency('arel', '~> 0.3.3')
27+
s.add_dependency('tzinfo', '~> 0.3.16')
2728
end

activerecord/lib/active_record/railties/databases.rake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ namespace :db do
435435
task :create => :environment do
436436
raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
437437
require 'rails/generators'
438+
Rails::Generators.configure!
438439
require 'rails/generators/rails/session_migration/session_migration_generator'
439440
Rails::Generators::SessionMigrationGenerator.start [ ENV["MIGRATION"] || "add_sessions_table" ]
440441
end

activerecord/lib/active_record/relation/query_methods.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module QueryMethods
99
(ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).each do |query_method|
1010
attr_accessor :"#{query_method}_values"
1111

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

24+
class_eval <<-CEVAL, __FILE__, __LINE__ + 1
25+
def select(*args, &block)
26+
if block_given?
27+
to_a.select(&block)
28+
else
29+
new_relation = clone
30+
value = Array.wrap(args.flatten).reject {|x| x.blank? }
31+
new_relation.select_values += value if value.present?
32+
new_relation
33+
end
34+
end
35+
CEVAL
36+
2437
[:where, :having].each do |query_method|
2538
class_eval <<-CEVAL, __FILE__, __LINE__ + 1
2639
def #{query_method}(*args, &block)

activerecord/test/cases/relations_test.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ def test_finding_with_group
112112
assert_equal 4, developers.map(&:salary).uniq.size
113113
end
114114

115+
def test_select_with_block
116+
even_ids = Developer.scoped.select {|d| d.id % 2 == 0 }.map(&:id)
117+
assert_equal [2, 4, 6, 8, 10], even_ids
118+
end
119+
115120
def test_finding_with_hash_conditions_on_joined_table
116121
firms = DependentFirm.joins(:account).where({:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}).to_a
117122
assert_equal 1, firms.size

0 commit comments

Comments
 (0)