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
jeremy committed Feb 6, 2009
2 parents 6f8ed1c + be098f8 commit 34f34e3
Show file tree
Hide file tree
Showing 149 changed files with 18,803 additions and 60 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -14,6 +14,7 @@ railties/pkg
railties/test/500.html
railties/doc/guides/html/images
railties/doc/guides/html/stylesheets
railties/guides/output
*.rbc
*.swp
*.swo
5 changes: 5 additions & 0 deletions actionmailer/CHANGELOG
@@ -1,3 +1,8 @@
*Edge*

* Fixed that ActionMailer should send correctly formatted Return-Path in MAIL FROM for SMTP #1842 [Matt Jones]


*2.3.0 [RC1] (February 1st, 2009)*

* Fixed RFC-2045 quoted-printable bug #1421 [squadette]
Expand Down
2 changes: 1 addition & 1 deletion actionmailer/lib/action_mailer/base.rb
Expand Up @@ -672,7 +672,7 @@ def create_mail
def perform_delivery_smtp(mail)
destinations = mail.destinations
mail.ready_to_send
sender = mail['return-path'] || mail.from
sender = (mail['return-path'] && mail['return-path'].spec) || mail.from

smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
Expand Down
1 change: 1 addition & 0 deletions actionmailer/test/mail_service_test.rb
Expand Up @@ -938,6 +938,7 @@ def test_return_path_with_deliver
ActionMailer::Base.delivery_method = :smtp
TestMailer.deliver_return_path
assert_match %r{^Return-Path: <another@somewhere.test>}, MockSMTP.deliveries[0][0]
assert_equal "another@somewhere.test", MockSMTP.deliveries[0][1].to_s
end

def test_body_is_stored_as_an_ivar
Expand Down
2 changes: 2 additions & 0 deletions actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*Edge*

* Fix a syntax error in current_page?() that was prevent matches against URL's with multiple query parameters #1385, #1868 [chris finne/Andrew White]

* Added localized rescue template when I18n.locale is set (ex: public/404.da.html) #1835 [José Valim]


Expand Down
7 changes: 2 additions & 5 deletions actionpack/lib/action_controller/dispatcher.rb
Expand Up @@ -7,7 +7,6 @@ def define_dispatcher_callbacks(cache_classes)
unless cache_classes
# Development mode callbacks
before_dispatch :reload_application
after_dispatch :cleanup_application

ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
end
Expand Down Expand Up @@ -93,11 +92,9 @@ def reload_application
run_callbacks :prepare_dispatch

Routing::Routes.reload
end

# Cleanup the application by clearing out loaded classes so they can
# be reloaded on the next request without restarting the server.
def cleanup_application
# Cleanup the application by clearing out loaded classes so they can
# be reloaded on the next request without restarting the server.
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
ActiveSupport::Dependencies.clear
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_controller/layout.rb
Expand Up @@ -173,7 +173,7 @@ def layout_conditions #:nodoc:
end

def default_layout(format) #:nodoc:
layout = read_inheritable_attribute(:layout)
layout = read_inheritable_attribute(:layout) unless format == :js
return layout unless read_inheritable_attribute(:auto_layout)
find_layout(layout, format)
end
Expand Down
25 changes: 22 additions & 3 deletions actionpack/lib/action_controller/session/abstract_store.rb
Expand Up @@ -58,9 +58,28 @@ def loaded?
end

def load!
@id, session = @by.send(:load_session, @env)
replace(session)
@loaded = true
stale_session_check! do
@id, session = @by.send(:load_session, @env)
replace(session)
@loaded = true
end
end

def stale_session_check!
yield
rescue ArgumentError => argument_error
if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
begin
# Note that the regexp does not allow $1 to end with a ':'
$1.constantize
rescue LoadError, NameError => const_error
raise ActionController::SessionRestoreError, "Session contains objects whose class definition isn\\'t available.\nRemember to require the classes for all objects kept in the session.\n(Original exception: \#{const_error.message} [\#{const_error.class}])\n"
end

retry
else
raise
end
end
end

Expand Down
3 changes: 2 additions & 1 deletion actionpack/lib/action_view/helpers/asset_tag_helper.rb
Expand Up @@ -516,7 +516,8 @@ def self.cache_asset_timestamps=(value)
def compute_public_path(source, dir, ext = nil, include_host = true)
has_request = @controller.respond_to?(:request)

if ext && (File.extname(source).blank? || File.exist?(File.join(ASSETS_DIR, dir, "#{source}.#{ext}")))
source_ext = File.extname(source)[1..-1]
if ext && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(ASSETS_DIR, dir, "#{source}.#{ext}"))))
source += ".#{ext}"
end

Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_view/helpers/atom_feed_helper.rb
Expand Up @@ -30,7 +30,7 @@ module AtomFeedHelper
# app/views/posts/index.atom.builder:
# atom_feed do |feed|
# feed.title("My great blog!")
# feed.updated((@posts.first.created_at))
# feed.updated(@posts.first.created_at)
#
# for post in @posts
# feed.entry(post) do |entry|
Expand Down
3 changes: 2 additions & 1 deletion actionpack/lib/action_view/helpers/form_helper.rb
Expand Up @@ -971,7 +971,8 @@ def fields_for_with_nested_attributes(association_name, args, block)
@template.fields_for(child_name, child, *args, &block)
end.join
else
@template.fields_for(name, association, *args, &block)
object = args.first.respond_to?(:new_record?) ? args.first : association
@template.fields_for(name, object, *args, &block)
end
end

Expand Down
27 changes: 25 additions & 2 deletions actionpack/lib/action_view/helpers/url_helper.rb
Expand Up @@ -507,7 +507,30 @@ def mail_to(email_address, name = nil, html_options = {})
# current_page?(:controller => 'shop', :action => 'checkout')
# # => true
#
# current_page?(:controller => 'shop', :action => 'checkout', :order => 'asc)
# current_page?(:controller => 'shop', :action => 'checkout', :order => 'asc')
# # => false
#
# current_page?(:action => 'checkout')
# # => true
#
# current_page?(:controller => 'library', :action => 'checkout')
# # => false
#
# Let's say we're in the <tt>/shop/checkout?order=desc&page=1</tt> action.
#
# current_page?(:action => 'process')
# # => false
#
# current_page?(:controller => 'shop', :action => 'checkout')
# # => true
#
# current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'1')
# # => true
#
# current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'2')
# # => false
#
# current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc')
# # => false
#
# current_page?(:action => 'checkout')
Expand All @@ -516,7 +539,7 @@ def mail_to(email_address, name = nil, html_options = {})
# current_page?(:controller => 'library', :action => 'checkout')
# # => false
def current_page?(options)
url_string = CGI.escapeHTML(url_for(options))
url_string = CGI.unescapeHTML(url_for(options))
request = @controller.request
# We ignore any extra parameters in the request_uri if the
# submitted url doesn't have any either. This lets the function
Expand Down
6 changes: 5 additions & 1 deletion actionpack/lib/action_view/paths.rb
Expand Up @@ -2,7 +2,11 @@ module ActionView #:nodoc:
class PathSet < Array #:nodoc:
def self.type_cast(obj)
if obj.is_a?(String)
Template::EagerPath.new(obj)
if !Object.const_defined?(:Rails) || Rails.configuration.cache_classes
Template::EagerPath.new(obj)
else
Template::Path.new(obj)
end
else
obj
end
Expand Down
11 changes: 10 additions & 1 deletion actionpack/test/controller/render_test.rb
Expand Up @@ -277,6 +277,9 @@ def render_explicit_html_template
def render_implicit_html_template_from_xhr_request
end

def render_implicit_js_template_without_layout
end

def formatted_html_erb
end

Expand Down Expand Up @@ -681,7 +684,8 @@ def determine_layout
"render_with_explicit_string_template",
"render_js_with_explicit_template",
"render_js_with_explicit_action_template",
"delete_with_js", "update_page", "update_page_with_instance_variables"
"delete_with_js", "update_page", "update_page_with_instance_variables",
"render_implicit_js_template_without_layout"

"layouts/standard"
when "action_talk_to_layout", "layout_overriding_layout"
Expand Down Expand Up @@ -1018,6 +1022,11 @@ def test_should_implicitly_render_html_template_from_xhr_request
assert_equal "Hello HTML!", @response.body
end

def test_should_implicitly_render_js_template_without_layout
get :render_implicit_js_template_without_layout, :format => :js
assert_no_match /<html>/, @response.body
end

def test_should_render_formatted_template
get :formatted_html_erb
assert_equal 'formatted html erb', @response.body
Expand Down
@@ -0,0 +1 @@
alert('hello');
9 changes: 9 additions & 0 deletions actionpack/test/template/form_helper_test.rb
Expand Up @@ -586,6 +586,15 @@ def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_a
assert_dom_equal expected, output_buffer
end

def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
form_for(:post, @post) do |f|
f.fields_for(:author, Author.new(123)) do |af|
assert_not_nil af.object
assert_equal 123, af.object.id
end
end
end

def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
@post.author = Author.new(321)

Expand Down
35 changes: 34 additions & 1 deletion actionpack/test/template/url_helper_test.rb
Expand Up @@ -252,6 +252,27 @@ def test_link_to_if
assert_equal "Showing", link_to_if(false, "Showing", :action => "show", :controller => "weblog", :id => 1)
end

def test_current_page_with_simple_url
@controller.request = RequestMock.new("http://www.example.com/weblog/show")
@controller.url = "http://www.example.com/weblog/show"
assert current_page?({ :action => "show", :controller => "weblog" })
assert current_page?("http://www.example.com/weblog/show")
end

def test_current_page_ignoring_params
@controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1")
@controller.url = "http://www.example.com/weblog/show?order=desc&page=1"
assert current_page?({ :action => "show", :controller => "weblog" })
assert current_page?("http://www.example.com/weblog/show")
end

def test_current_page_with_params_that_match
@controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1")
@controller.url = "http://www.example.com/weblog/show?order=desc&page=1"
assert current_page?({ :action => "show", :controller => "weblog", :order => "desc", :page => "1" })
assert current_page?("http://www.example.com/weblog/show?order=desc&amp;page=1")
end

def test_link_unless_current
@controller.request = RequestMock.new("http://www.example.com/weblog/show")
@controller.url = "http://www.example.com/weblog/show"
Expand All @@ -263,11 +284,23 @@ def test_link_unless_current
assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" })
assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show")

@controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1")
@controller.url = "http://www.example.com/weblog/show?order=desc&page=1"
assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog", :order=>'desc', :page=>'1' })
assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&amp;page=1")
assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=1")

@controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc")
@controller.url = "http://www.example.com/weblog/show?order=asc"
assert_equal "<a href=\"http://www.example.com/weblog/show?order=asc\">Showing</a>", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" })
assert_equal "<a href=\"http://www.example.com/weblog/show?order=asc\">Showing</a>", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=asc")

@controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1")
@controller.url = "http://www.example.com/weblog/show?order=desc&page=2"
assert_equal "<a href=\"http://www.example.com/weblog/show?order=desc&amp;page=2\">Showing</a>", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" })
assert_equal "<a href=\"http://www.example.com/weblog/show?order=desc&amp;page=2\">Showing</a>", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=2")


@controller.request = RequestMock.new("http://www.example.com/weblog/show")
@controller.url = "http://www.example.com/weblog/list"
assert_equal "<a href=\"http://www.example.com/weblog/list\">Listing</a>",
Expand Down Expand Up @@ -319,7 +352,7 @@ def test_mail_to_with_replace_options
assert_dom_equal "<script type=\"text/javascript\">eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", "My email", :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)")
assert_dom_equal "<script type=\"text/javascript\">eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%6d%65%28%61%74%29%64%6f%6d%61%69%6e%28%64%6f%74%29%63%6f%6d%3c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", nil, :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)")
end

def protect_against_forgery?
false
end
Expand Down
5 changes: 5 additions & 0 deletions activerecord/CHANGELOG
@@ -1,3 +1,8 @@
*Edge*

* Added that ActiveRecord::Base.exists? can be called with no arguments #1817 [Scott Taylor]


*2.3.0 [RC1] (February 1st, 2009)*

* Add Support for updating deeply nested models from a single form. #1202 [Eloy Duran]
Expand Down
16 changes: 16 additions & 0 deletions activerecord/lib/active_record/associations.rb
Expand Up @@ -1090,6 +1090,22 @@ def belongs_to(association_id, options = {})
# but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the
# custom <tt>:join_table</tt> option if you need to.
#
# The join table should not have a primary key or a model associated with it. You must manually generate the
# join table with a migration such as this:
#
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
# def self.up
# create_table :developers_projects, :id => false do |t|
# t.integer :developer_id
# t.integer :project_id
# end
# end
#
# def self.down
# drop_table :developers_projects
# end
# end
#
# Deprecated: Any additional fields added to the join table will be placed as attributes when pulling records out through
# +has_and_belongs_to_many+ associations. Records returned from join tables with additional attributes will be marked as
# readonly (because we can't save changes to the additional attributes). It's strongly recommended that you upgrade any
Expand Down
1 change: 1 addition & 0 deletions activerecord/lib/active_record/attribute_methods.rb
Expand Up @@ -324,6 +324,7 @@ def query_attribute(attr_name)
if Numeric === value || value !~ /[^0-9]/
!value.to_i.zero?
else
return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
!value.blank?
end
elsif column.number?
Expand Down
12 changes: 12 additions & 0 deletions activerecord/lib/active_record/autosave_association.rb
Expand Up @@ -129,6 +129,7 @@ def self.included(base)
base.class_eval do
alias_method_chain :reload, :autosave_associations
alias_method_chain :save, :autosave_associations
alias_method_chain :save!, :autosave_associations
alias_method_chain :valid?, :autosave_associations

%w{ has_one belongs_to has_many has_and_belongs_to_many }.each do |type|
Expand Down Expand Up @@ -161,6 +162,17 @@ def save_with_autosave_associations(perform_validation = true)
end
end

# Attempts to save the record just like save_with_autosave_associations but
# will raise a RecordInvalid exception instead of returning false if the
# record is not valid.
def save_with_autosave_associations!
if valid_with_autosave_associations?
save_with_autosave_associations(false) || raise(RecordNotSaved)
else
raise RecordInvalid.new(self)
end
end

# Returns whether or not the parent, <tt>self</tt>, and any loaded autosave associations are valid.
def valid_with_autosave_associations?
if valid_without_autosave_associations?
Expand Down

0 comments on commit 34f34e3

Please sign in to comment.