mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge branch 'master' of git@github.com:rails/rails
This commit is contained in:
commit
74fd17346f
72 changed files with 292 additions and 140 deletions
|
@ -1,4 +1,4 @@
|
|||
*SVN*
|
||||
*2.1.0 RC1 (May 11th, 2008)*
|
||||
|
||||
* Fixed that a return-path header would be ignored #7572 [joost]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -55,7 +55,7 @@ spec = Gem::Specification.new do |s|
|
|||
s.rubyforge_project = "actionmailer"
|
||||
s.homepage = "http://www.rubyonrails.org"
|
||||
|
||||
s.add_dependency('actionpack', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('actionpack', '= 2.0.991' + PKG_BUILD)
|
||||
|
||||
s.has_rdoc = true
|
||||
s.requirements << 'none'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#--
|
||||
# Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -2,7 +2,7 @@ module ActionMailer
|
|||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 0
|
||||
TINY = 2
|
||||
TINY = 991
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
*SVN*
|
||||
*2.1.0 RC1 (May 11th, 2008)*
|
||||
|
||||
* Fixed that forgery protection can be used without session tracking (Peter Jones) [#139]
|
||||
|
||||
* Added session(:on) to turn session management back on in a controller subclass if the superclass turned it off (Peter Jones) [#136]
|
||||
|
||||
* Change the request forgery protection to go by Content-Type instead of request.format so that you can't bypass it by POSTing to "#{request.uri}.xml" [rick]
|
||||
* InstanceTag#default_time_from_options with hash args uses Time.current as default; respects hash settings when time falls in system local spring DST gap [Geoff Buesing]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -76,7 +76,7 @@ spec = Gem::Specification.new do |s|
|
|||
s.has_rdoc = true
|
||||
s.requirements << 'none'
|
||||
|
||||
s.add_dependency('activesupport', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('activesupport', '= 2.0.991' + PKG_BUILD)
|
||||
|
||||
s.require_path = 'lib'
|
||||
s.autorequire = 'action_controller'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#--
|
||||
# Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -37,7 +37,7 @@ class CGI #:nodoc:
|
|||
@path = nil
|
||||
else
|
||||
@name = name['name']
|
||||
@value = Array(name['value'])
|
||||
@value = name['value'].kind_of?(String) ? [name['value']] : Array(name['value'])
|
||||
@domain = name['domain']
|
||||
@expires = name['expires']
|
||||
@secure = name['secure'] || false
|
||||
|
|
|
@ -28,7 +28,6 @@ module ActionController #:nodoc:
|
|||
base.class_eval do
|
||||
include InstanceMethods
|
||||
alias_method_chain :assign_shortcuts, :flash
|
||||
alias_method_chain :process_cleanup, :flash
|
||||
alias_method_chain :reset_session, :flash
|
||||
end
|
||||
end
|
||||
|
@ -166,11 +165,7 @@ module ActionController #:nodoc:
|
|||
def assign_shortcuts_with_flash(request, response) #:nodoc:
|
||||
assign_shortcuts_without_flash(request, response)
|
||||
flash(:refresh)
|
||||
end
|
||||
|
||||
def process_cleanup_with_flash
|
||||
flash.sweep if @_session
|
||||
process_cleanup_without_flash
|
||||
flash.sweep if @_session && !component_request?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -105,12 +105,12 @@ module ActionController #:nodoc:
|
|||
# Sets the token value for the current session. Pass a <tt>:secret</tt> option
|
||||
# in +protect_from_forgery+ to add a custom salt to the hash.
|
||||
def form_authenticity_token
|
||||
@form_authenticity_token ||= if request_forgery_protection_options[:secret]
|
||||
@form_authenticity_token ||= if !session.respond_to?(:session_id)
|
||||
raise InvalidAuthenticityToken, "Request Forgery Protection requires a valid session. Use #allow_forgery_protection to disable it, or use a valid session."
|
||||
elsif request_forgery_protection_options[:secret]
|
||||
authenticity_token_from_session_id
|
||||
elsif session.respond_to?(:dbman) && session.dbman.respond_to?(:generate_digest)
|
||||
authenticity_token_from_cookie_session
|
||||
elsif session.nil?
|
||||
raise InvalidAuthenticityToken, "Request Forgery Protection requires a valid session. Use #allow_forgery_protection to disable it, or use a valid session."
|
||||
else
|
||||
raise InvalidAuthenticityToken, "No :secret given to the #protect_from_forgery call. Set that or use a session store capable of generating its own keys (Cookie Session Store)."
|
||||
end
|
||||
|
|
|
@ -199,10 +199,8 @@ module ActionController #:nodoc:
|
|||
private
|
||||
def perform_action_with_rescue #:nodoc:
|
||||
perform_action_without_rescue
|
||||
rescue Exception => exception # errors from action performed
|
||||
return if rescue_action_with_handler(exception)
|
||||
|
||||
rescue_action(exception)
|
||||
rescue Exception => exception
|
||||
rescue_action_with_handler(exception) || rescue_action(exception)
|
||||
end
|
||||
|
||||
def rescues_path(template_name)
|
||||
|
|
|
@ -130,17 +130,20 @@ class CGI::Session::CookieStore
|
|||
# Marshal a session hash into safe cookie data. Include an integrity hash.
|
||||
def marshal(session)
|
||||
data = ActiveSupport::Base64.encode64(Marshal.dump(session)).chop
|
||||
CGI.escape "#{data}--#{generate_digest(data)}"
|
||||
"#{data}--#{generate_digest(data)}"
|
||||
end
|
||||
|
||||
# Unmarshal cookie data to a hash and verify its integrity.
|
||||
def unmarshal(cookie)
|
||||
if cookie
|
||||
data, digest = CGI.unescape(cookie).split('--')
|
||||
unless digest == generate_digest(data)
|
||||
data, digest = cookie.split('--')
|
||||
|
||||
# Do two checks to transparently support old double-escaped data.
|
||||
unless digest == generate_digest(data) || digest == generate_digest(data = CGI.unescape(data))
|
||||
delete
|
||||
raise TamperedWithCookie
|
||||
end
|
||||
|
||||
Marshal.load(ActiveSupport::Base64.decode64(data))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -69,11 +69,16 @@ module ActionController #:nodoc:
|
|||
# session :off,
|
||||
# :if => Proc.new { |req| !(req.format.html? || req.format.js?) }
|
||||
#
|
||||
# # turn the session back on, useful when it was turned off in the
|
||||
# # application controller, and you need it on in another controller
|
||||
# session :on
|
||||
#
|
||||
# All session options described for ActionController::Base.process_cgi
|
||||
# are valid arguments.
|
||||
def session(*args)
|
||||
options = args.extract_options!
|
||||
|
||||
options[:disabled] = false if args.delete(:on)
|
||||
options[:disabled] = true if !args.empty?
|
||||
options[:only] = [*options[:only]].map { |o| o.to_s } if options[:only]
|
||||
options[:except] = [*options[:except]].map { |o| o.to_s } if options[:except]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#--
|
||||
# Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -2,7 +2,7 @@ module ActionPack #:nodoc:
|
|||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 0
|
||||
TINY = 2
|
||||
TINY = 991
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#--
|
||||
# Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
||||
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
|
||||
// Contributors:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Contributors:
|
||||
// Justin Palmer (http://encytemedia.com/)
|
||||
// Mark Pilgrim (http://diveintomark.org/)
|
||||
|
|
|
@ -48,6 +48,11 @@ module ActionView
|
|||
# config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
|
||||
# end
|
||||
#
|
||||
# Please note that sanitizing user-provided text does not guarantee that the
|
||||
# resulting markup is valid (conforming to a document type) or even well-formed.
|
||||
# The output may still contain e.g. unescaped '<', '>', '&' characters and
|
||||
# confuse browsers.
|
||||
#
|
||||
def sanitize(html, options = {})
|
||||
self.class.white_list_sanitizer.sanitize(html, options)
|
||||
end
|
||||
|
|
|
@ -137,4 +137,9 @@ class CookieTest < Test::Unit::TestCase
|
|||
cookies = CGI::Cookie.parse('return_to=http://rubyonrails.org/search?term=api&scope=all&global=true')
|
||||
assert_equal({"return_to" => ["http://rubyonrails.org/search?term=api&scope=all&global=true"]}, cookies)
|
||||
end
|
||||
|
||||
def test_cookies_should_not_be_split_on_values_with_newlines
|
||||
cookies = CGI::Cookie.new("name" => "val", "value" => "this\nis\na\ntest")
|
||||
assert cookies.size == 1
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,6 +50,14 @@ class CsrfCookieMonsterController < ActionController::Base
|
|||
protect_from_forgery :only => :index
|
||||
end
|
||||
|
||||
# sessions are turned off
|
||||
class SessionOffController < ActionController::Base
|
||||
protect_from_forgery :secret => 'foobar'
|
||||
session :off
|
||||
def rescue_action(e) raise e end
|
||||
include RequestForgeryProtectionActions
|
||||
end
|
||||
|
||||
class FreeCookieController < CsrfCookieMonsterController
|
||||
self.allow_forgery_protection = false
|
||||
|
||||
|
@ -287,3 +295,19 @@ class FreeCookieControllerTest < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
class SessionOffControllerTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@controller = SessionOffController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
|
||||
end
|
||||
|
||||
def test_should_raise_correct_exception
|
||||
@request.session = {} # session(:off) doesn't appear to work with controller tests
|
||||
assert_raises(ActionController::InvalidAuthenticityToken) do
|
||||
post :index, :authenticity_token => @token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,9 @@ class CookieStoreTest < Test::Unit::TestCase
|
|||
{ :empty => ['BAgw--0686dcaccc01040f4bd4f35fe160afe9bc04c330', {}],
|
||||
:a_one => ['BAh7BiIGYWkG--5689059497d7f122a7119f171aef81dcfd807fec', { 'a' => 1 }],
|
||||
:typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--9d20154623b9eeea05c62ab819be0e2483238759', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
|
||||
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }] }
|
||||
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA==--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }],
|
||||
:double_escaped => [CGI.escape('BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf'), { 'user_id' => 123, 'flash' => {} }] }
|
||||
|
||||
end
|
||||
|
||||
def setup
|
||||
|
@ -101,6 +103,15 @@ class CookieStoreTest < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_restores_double_encoded_cookies
|
||||
set_cookie! cookie_value(:double_escaped)
|
||||
new_session do |session|
|
||||
session.dbman.restore
|
||||
assert_equal session["user_id"], 123
|
||||
assert_equal session["flash"], {}
|
||||
end
|
||||
end
|
||||
|
||||
def test_close_doesnt_write_cookie_if_data_is_blank
|
||||
new_session do |session|
|
||||
assert_no_cookies session
|
||||
|
@ -241,6 +252,7 @@ class CookieStoreWithMD5DigestTest < CookieStoreTest
|
|||
{ :empty => ['BAgw--0415cc0be9579b14afc22ee2d341aa21', {}],
|
||||
:a_one => ['BAh7BiIGYWkG--5a0ed962089cc6600ff44168a5d59bc8', { 'a' => 1 }],
|
||||
:typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--f426763f6ef435b3738b493600db8d64', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
|
||||
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }] }
|
||||
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA==--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }],
|
||||
:double_escaped => [CGI.escape('BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--0af9156650dab044a53a91a4ddec2c51'), { 'user_id' => 123, 'flash' => {} }] }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,19 @@ class SessionManagementTest < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
class SessionOffOnController < ActionController::Base
|
||||
session :off
|
||||
session :on, :only => :tell
|
||||
|
||||
def show
|
||||
render :text => "done"
|
||||
end
|
||||
|
||||
def tell
|
||||
render :text => "done"
|
||||
end
|
||||
end
|
||||
|
||||
class TestController < ActionController::Base
|
||||
session :off, :only => :show
|
||||
session :session_secure => true, :except => :show
|
||||
|
@ -100,6 +113,15 @@ class SessionManagementTest < Test::Unit::TestCase
|
|||
assert_equal false, @request.session_options
|
||||
end
|
||||
|
||||
def test_session_off_then_on_globally
|
||||
@controller = SessionOffOnController.new
|
||||
get :show
|
||||
assert_equal false, @request.session_options
|
||||
get :tell
|
||||
assert_instance_of Hash, @request.session_options
|
||||
assert_equal false, @request.session_options[:disabled]
|
||||
end
|
||||
|
||||
def test_session_off_conditionally
|
||||
@controller = TestController.new
|
||||
get :show
|
||||
|
|
|
@ -12,6 +12,11 @@ class TestTest < Test::Unit::TestCase
|
|||
render :text => 'ignore me'
|
||||
end
|
||||
|
||||
def set_flash_now
|
||||
flash.now["test_now"] = ">#{flash["test_now"]}<"
|
||||
render :text => 'ignore me'
|
||||
end
|
||||
|
||||
def set_session
|
||||
session['string'] = 'A wonder'
|
||||
session[:symbol] = 'it works'
|
||||
|
@ -145,6 +150,11 @@ XML
|
|||
assert_equal '>value<', flash['test']
|
||||
end
|
||||
|
||||
def test_process_with_flash_now
|
||||
process :set_flash_now, nil, nil, { "test_now" => "value_now" }
|
||||
assert_equal '>value_now<', flash['test_now']
|
||||
end
|
||||
|
||||
def test_process_with_session
|
||||
process :set_session
|
||||
assert_equal 'A wonder', session['string'], "A value stored in the session should be available by string key"
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
*SVN*
|
||||
*2.1.0 RC1 (May 11th, 2008)*
|
||||
|
||||
* Ensure hm:t preloading honours reflection options. Resolves #137. [Frederick Cheung]
|
||||
|
||||
* Added protection against duplicate migration names (Aslak Hellesøy) [#112]
|
||||
|
||||
* Base#instantiate_time_object: eliminate check for Time.zone, since we can assume this is set if time_zone_aware_attributes is set to true [Geoff Buesing]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -171,7 +171,7 @@ spec = Gem::Specification.new do |s|
|
|||
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
||||
end
|
||||
|
||||
s.add_dependency('activesupport', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('activesupport', '= 2.0.991' + PKG_BUILD)
|
||||
|
||||
s.files.delete FIXTURES_ROOT + "/fixture_database.sqlite"
|
||||
s.files.delete FIXTURES_ROOT + "/fixture_database_2.sqlite"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#--
|
||||
# Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -31,12 +31,12 @@ module ActiveRecord
|
|||
private
|
||||
|
||||
def preload_one_association(records, association, preload_options={})
|
||||
reflection = reflections[association]
|
||||
raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
|
||||
|
||||
# Not all records have the same class, so group then preload.
|
||||
records.group_by(&:class).each do |klass, records|
|
||||
reflection = klass.reflections[association]
|
||||
class_to_reflection = {}
|
||||
# Not all records have the same class, so group then preload
|
||||
# group on the reflection itself so that if various subclass share the same association then we do not split them
|
||||
# unncessarily
|
||||
records.group_by {|record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, records|
|
||||
raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
|
||||
send("preload_#{reflection.macro}_association", records, reflection, preload_options)
|
||||
end
|
||||
end
|
||||
|
@ -143,7 +143,8 @@ module ActiveRecord
|
|||
through_primary_key = through_reflection.primary_key_name
|
||||
unless through_records.empty?
|
||||
source = reflection.source_reflection.name
|
||||
through_records.first.class.preload_associations(through_records, source)
|
||||
#add conditions from reflection!
|
||||
through_records.first.class.preload_associations(through_records, source, reflection.options)
|
||||
through_records.each do |through_record|
|
||||
add_preloaded_records_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
|
||||
reflection.name, through_record.send(source))
|
||||
|
@ -251,12 +252,12 @@ module ActiveRecord
|
|||
conditions << append_conditions(options, preload_options)
|
||||
|
||||
reflection.klass.find(:all,
|
||||
:select => (options[:select] || "#{table_name}.*"),
|
||||
:include => options[:include],
|
||||
:select => (preload_options[:select] || options[:select] || "#{table_name}.*"),
|
||||
:include => preload_options[:include] || options[:include],
|
||||
:conditions => [conditions, ids],
|
||||
:joins => options[:joins],
|
||||
:group => options[:group],
|
||||
:order => options[:order])
|
||||
:group => preload_options[:group] || options[:group],
|
||||
:order => preload_options[:order] || options[:order])
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1910,6 +1910,8 @@ module ActiveRecord #:nodoc:
|
|||
# { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
|
||||
# "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
|
||||
def sanitize_sql_for_conditions(condition)
|
||||
return nil if condition.blank?
|
||||
|
||||
case condition
|
||||
when Array; sanitize_sql_array(condition)
|
||||
when Hash; sanitize_sql_hash_for_conditions(condition)
|
||||
|
@ -2340,7 +2342,7 @@ module ActiveRecord #:nodoc:
|
|||
|
||||
|
||||
# Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
|
||||
def attributes(options = nil)
|
||||
def attributes
|
||||
self.attribute_names.inject({}) do |attrs, name|
|
||||
attrs[name] = read_attribute(name)
|
||||
attrs
|
||||
|
|
|
@ -69,19 +69,19 @@ module ActiveRecord
|
|||
changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
|
||||
end
|
||||
|
||||
|
||||
# Clear changed attributes after they are saved.
|
||||
# Attempts to +save+ the record and clears changed attributes if successful.
|
||||
def save_with_dirty(*args) #:nodoc:
|
||||
save_without_dirty(*args)
|
||||
ensure
|
||||
changed_attributes.clear
|
||||
if status = save_without_dirty(*args)
|
||||
changed_attributes.clear
|
||||
end
|
||||
status
|
||||
end
|
||||
|
||||
# Clear changed attributes after they are saved.
|
||||
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
|
||||
def save_with_dirty!(*args) #:nodoc:
|
||||
save_without_dirty!(*args)
|
||||
ensure
|
||||
status = save_without_dirty!(*args)
|
||||
changed_attributes.clear
|
||||
status
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -8,6 +8,12 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class DuplicateMigrationNameError < ActiveRecordError#:nodoc:
|
||||
def initialize(name)
|
||||
super("Multiple migrations have the name #{name}")
|
||||
end
|
||||
end
|
||||
|
||||
class UnknownMigrationVersionError < ActiveRecordError #:nodoc:
|
||||
def initialize(version)
|
||||
super("No migration with version number #{version}")
|
||||
|
@ -440,6 +446,10 @@ module ActiveRecord
|
|||
if klasses.detect { |m| m.version == version }
|
||||
raise DuplicateMigrationVersionError.new(version)
|
||||
end
|
||||
|
||||
if klasses.detect { |m| m.name == name.camelize }
|
||||
raise DuplicateMigrationNameError.new(name.camelize)
|
||||
end
|
||||
|
||||
load(file)
|
||||
|
||||
|
|
|
@ -71,6 +71,18 @@ module ActiveRecord
|
|||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
# For testing complex named scopes, you can examine the scoping options using the
|
||||
# <tt>proxy_options</tt> method on the proxy itself.
|
||||
#
|
||||
# class Shirt < ActiveRecord::Base
|
||||
# named_scope :colored, lambda { |color|
|
||||
# { :conditions => { :color => color } }
|
||||
# }
|
||||
# end
|
||||
#
|
||||
# expected_options = { :conditions => { :colored => 'red' } }
|
||||
# assert_equal expected_options, Shirt.colored('red').proxy_options
|
||||
def named_scope(name, options = {}, &block)
|
||||
scopes[name] = lambda do |parent_scope, *args|
|
||||
Scope.new(parent_scope, case options
|
||||
|
|
|
@ -640,7 +640,7 @@ module ActiveRecord
|
|||
results = finder_class.with_exclusive_scope do
|
||||
connection.select_all(
|
||||
construct_finder_sql(
|
||||
:select => "#{attr_name}",
|
||||
:select => "#{connection.quote_column_name(attr_name)}",
|
||||
:from => "#{finder_class.quoted_table_name}",
|
||||
:conditions => [condition_sql, *condition_params]
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@ module ActiveRecord
|
|||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 0
|
||||
TINY = 2
|
||||
TINY = 991
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
|
|
|
@ -275,6 +275,17 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|||
Author.find(:first, :order => 'authors.id').hello_post_comments.sort_by(&:id)
|
||||
end
|
||||
|
||||
def test_eager_with_has_many_through_join_model_with_conditions_on_top_level
|
||||
assert_equal comments(:more_greetings), Author.find(authors(:david).id, :include => :comments_with_order_and_conditions).comments_with_order_and_conditions.first
|
||||
end
|
||||
|
||||
def test_eager_with_has_many_through_join_model_with_include
|
||||
author_comments = Author.find(authors(:david).id, :include => :comments_with_include).comments_with_include.to_a
|
||||
assert_no_queries do
|
||||
author_comments.first.post.title
|
||||
end
|
||||
end
|
||||
|
||||
def test_eager_with_has_many_and_limit
|
||||
posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2)
|
||||
assert_equal 2, posts.size
|
||||
|
@ -592,4 +603,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|||
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
|
||||
end
|
||||
end
|
||||
|
||||
def test_load_with_sti_sharing_association
|
||||
assert_queries(2) do #should not do 1 query per subclass
|
||||
Comment.find :all, :include => :post
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|||
assert_equal 2, Firm.find(:first).clients.length
|
||||
end
|
||||
|
||||
def test_find_with_blank_conditions
|
||||
[[], {}, nil, ""].each do |blank|
|
||||
assert_equal 2, Firm.find(:first).clients.find(:all, :conditions => blank).size
|
||||
end
|
||||
end
|
||||
|
||||
def test_find_many_with_merged_options
|
||||
assert_equal 1, companies(:first_firm).limited_clients.size
|
||||
assert_equal 1, companies(:first_firm).limited_clients.find(:all).size
|
||||
|
@ -851,4 +857,4 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|||
assert ! firm.clients.include?(client)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ class DirtyTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_association_assignment_changes_foreign_key
|
||||
pirate = Pirate.create!
|
||||
pirate = Pirate.create!(:catchphrase => 'jarl')
|
||||
pirate.parrot = Parrot.create!
|
||||
assert pirate.changed?
|
||||
assert_equal %w(parrot_id), pirate.changed
|
||||
|
@ -115,6 +115,18 @@ class DirtyTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_changed_attributes_should_be_preserved_if_save_failure
|
||||
pirate = Pirate.new
|
||||
pirate.parrot_id = 1
|
||||
assert !pirate.save
|
||||
check_pirate_after_save_failure(pirate)
|
||||
|
||||
pirate = Pirate.new
|
||||
pirate.parrot_id = 1
|
||||
assert_raises(ActiveRecord::RecordInvalid) { pirate.save! }
|
||||
check_pirate_after_save_failure(pirate)
|
||||
end
|
||||
|
||||
private
|
||||
def with_partial_updates(klass, on = true)
|
||||
old = klass.partial_updates?
|
||||
|
@ -123,4 +135,11 @@ class DirtyTest < ActiveRecord::TestCase
|
|||
ensure
|
||||
klass.partial_updates = old
|
||||
end
|
||||
|
||||
def check_pirate_after_save_failure(pirate)
|
||||
assert pirate.changed?
|
||||
assert pirate.parrot_id_changed?
|
||||
assert_equal %w(parrot_id), pirate.changed
|
||||
assert_nil pirate.parrot_id_was
|
||||
end
|
||||
end
|
||||
|
|
|
@ -984,6 +984,12 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|||
end
|
||||
end
|
||||
|
||||
def test_migrator_with_duplicate_names
|
||||
assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do
|
||||
ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate_names", nil)
|
||||
end
|
||||
end
|
||||
|
||||
def test_migrator_with_missing_version_numbers
|
||||
assert_raise(ActiveRecord::UnknownMigrationVersionError) do
|
||||
ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/missing", 500)
|
||||
|
|
|
@ -112,4 +112,10 @@ class NamedScopeTest < ActiveRecord::TestCase
|
|||
|
||||
assert_equal Topic.find(:all, scope), Topic.scoped(scope)
|
||||
end
|
||||
|
||||
def test_proxy_options
|
||||
expected_proxy_options = { :conditions => { :approved => true } }
|
||||
assert_equal expected_proxy_options, Topic.approved.proxy_options
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ require 'models/reply'
|
|||
require 'models/person'
|
||||
require 'models/developer'
|
||||
require 'models/warehouse_thing'
|
||||
require 'models/guid'
|
||||
|
||||
# The following methods in Topic are used in test_conditional_validation_*
|
||||
class Topic
|
||||
|
@ -493,6 +494,13 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_with_columns_which_are_sql_keywords
|
||||
Guid.validates_uniqueness_of :key
|
||||
g = Guid.new
|
||||
g.key = "foo"
|
||||
assert_nothing_raised { !g.valid? }
|
||||
end
|
||||
|
||||
def test_validate_straight_inheritance_uniqueness
|
||||
w1 = IneptWizard.create(:name => "Rincewind", :city => "Ankh-Morpork")
|
||||
assert w1.valid?, "Saving w1"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
class Chunky < ActiveRecord::Migration
|
||||
def self.up
|
||||
end
|
||||
|
||||
def self.down
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
class Chunky < ActiveRecord::Migration
|
||||
def self.up
|
||||
end
|
||||
|
||||
def self.down
|
||||
end
|
||||
end
|
|
@ -17,6 +17,10 @@ class Author < ActiveRecord::Base
|
|||
end
|
||||
has_many :comments, :through => :posts
|
||||
has_many :comments_containing_the_letter_e, :through => :posts, :source => :comments
|
||||
has_many :comments_with_order_and_conditions, :through => :posts, :source => :comments, :order => 'comments.body', :conditions => "comments.body like 'Thank%'"
|
||||
has_many :comments_with_include, :through => :posts, :source => :comments, :include => :post
|
||||
|
||||
|
||||
has_many :comments_desc, :through => :posts, :source => :comments, :order => 'comments.id DESC'
|
||||
has_many :limited_comments, :through => :posts, :source => :comments, :limit => 1
|
||||
has_many :funky_comments, :through => :posts, :source => :comments
|
||||
|
|
2
activerecord/test/models/guid.rb
Normal file
2
activerecord/test/models/guid.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
class Guid < ActiveRecord::Base
|
||||
end
|
|
@ -4,4 +4,6 @@ class Pirate < ActiveRecord::Base
|
|||
has_many :treasures, :as => :looter
|
||||
|
||||
has_many :treasure_estimates, :through => :treasures, :source => :price_estimates
|
||||
|
||||
validates_presence_of :catchphrase
|
||||
end
|
||||
|
|
|
@ -403,6 +403,10 @@ ActiveRecord::Schema.define do
|
|||
create_table(t, :force => true) { }
|
||||
end
|
||||
|
||||
create_table :guids, :force => true do |t|
|
||||
t.column :key, :string
|
||||
end
|
||||
|
||||
except 'SQLite' do
|
||||
# fk_test_has_fk should be before fk_test_has_pk
|
||||
create_table :fk_test_has_fk, :force => true do |t|
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
*SVN*
|
||||
*2.1.0 RC1 (May 11th, 2008)*
|
||||
|
||||
* Fixed response logging to use length instead of the entire thing (seangeo) [#27]
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ spec = Gem::Specification.new do |s|
|
|||
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
||||
end
|
||||
|
||||
s.add_dependency('activesupport', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('activesupport', '= 2.0.991' + PKG_BUILD)
|
||||
|
||||
s.require_path = 'lib'
|
||||
s.autorequire = 'active_resource'
|
||||
|
|
|
@ -2,7 +2,7 @@ module ActiveResource
|
|||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 0
|
||||
TINY = 2
|
||||
TINY = 991
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
*SVN*
|
||||
*2.1.0 RC1 (May 11th, 2008)*
|
||||
|
||||
* Remove unused JSON::RESERVED_WORDS, JSON.valid_identifier? and JSON.reserved_word? methods. Resolves #164. [Cheah Chu Yeow]
|
||||
|
||||
* Adding Date.current, which returns Time.zone.today if config.time_zone is set; otherwise returns Date.today [Geoff Buesing]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2005-2007 David Heinemeier Hansson
|
||||
Copyright (c) 2005-2008 David Heinemeier Hansson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -128,7 +128,7 @@ class Class # :nodoc:
|
|||
new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
|
||||
else
|
||||
new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
|
||||
memo.update(key => (value.dup rescue value))
|
||||
memo.update(key => value.duplicable? ? value.dup : value)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -176,19 +176,6 @@ module ActiveSupport
|
|||
end
|
||||
end
|
||||
|
||||
class DeprecatedInstanceVariable < Delegator #:nodoc:
|
||||
def initialize(value, method)
|
||||
super(value)
|
||||
@method = method
|
||||
@value = value
|
||||
end
|
||||
|
||||
def __getobj__
|
||||
ActiveSupport::Deprecation.warn("Instance variable @#{@method} is deprecated! Call instance method #{@method} instead.")
|
||||
@value
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
module ActiveSupport
|
||||
# If true, use ISO 8601 format for dates and times. Otherwise, fall back to the ActiveSupport legacy format.
|
||||
mattr_accessor :use_standard_json_time_format
|
||||
|
@ -19,33 +17,6 @@ module ActiveSupport
|
|||
@escape_html_entities_in_json = value
|
||||
end
|
||||
end
|
||||
|
||||
module JSON
|
||||
RESERVED_WORDS = %w(
|
||||
abstract delete goto private transient
|
||||
boolean do if protected try
|
||||
break double implements public typeof
|
||||
byte else import return var
|
||||
case enum in short void
|
||||
catch export instanceof static volatile
|
||||
char extends int super while
|
||||
class final interface switch with
|
||||
const finally long synchronized
|
||||
continue float native this
|
||||
debugger for new throw
|
||||
default function package throws
|
||||
) #:nodoc:
|
||||
|
||||
class << self
|
||||
def valid_identifier?(key) #:nodoc:
|
||||
key.to_s =~ /^[[:alpha:]_$][[:alnum:]_$]*$/ && !reserved_word?(key)
|
||||
end
|
||||
|
||||
def reserved_word?(key) #:nodoc:
|
||||
RESERVED_WORDS.include?(key.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'active_support/json/encoding'
|
||||
|
|
|
@ -2,7 +2,7 @@ module ActiveSupport
|
|||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 0
|
||||
TINY = 2
|
||||
TINY = 991
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
|
|
|
@ -149,13 +149,3 @@ class DeprecationTest < Test::Unit::TestCase
|
|||
assert_nil @last_message
|
||||
end
|
||||
end
|
||||
|
||||
class DeprecatedIvarTest < Test::Unit::TestCase
|
||||
|
||||
def test_deprecated_ivar
|
||||
@action = ActiveSupport::Deprecation::DeprecatedInstanceVariable.new("fubar", :foobar)
|
||||
|
||||
assert_deprecated(/Instance variable @foobar is deprecated! Call instance method foobar instead/) { assert_equal "fubar", @action }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
unless ARGV.first == "no_build"
|
||||
build_number = build_number = `svn log -q -rhead http://dev.rubyonrails.org/svn/rails`.scan(/r([0-9]*)/).first.first.to_i
|
||||
build_number = Time.now.strftime("%Y%m%d%H%M%S").to_i
|
||||
end
|
||||
|
||||
%w( activeresource actionmailer actionpack activerecord railties activesupport ).each do |pkg|
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
*SVN*
|
||||
*2.1.0 RC1 (May 11th, 2008)*
|
||||
|
||||
* script/dbconsole fires up the command-line database client. #102 [Steve Purcell]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -255,7 +255,7 @@ task :generate_rails_framework_doc do
|
|||
end
|
||||
|
||||
task :generate_app_doc do
|
||||
File.cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP"
|
||||
cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP"
|
||||
system %{cd #{PKG_DESTINATION}; rake doc:app}
|
||||
end
|
||||
|
||||
|
@ -303,12 +303,12 @@ spec = Gem::Specification.new do |s|
|
|||
on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.
|
||||
EOF
|
||||
|
||||
s.add_dependency('rake', '>= 0.7.2')
|
||||
s.add_dependency('activesupport', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('activerecord', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('actionpack', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('actionmailer', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('activeresource', '= 2.0.2' + PKG_BUILD)
|
||||
s.add_dependency('rake', '>= 0.8.1')
|
||||
s.add_dependency('activesupport', '= 2.0.991' + PKG_BUILD)
|
||||
s.add_dependency('activerecord', '= 2.0.991' + PKG_BUILD)
|
||||
s.add_dependency('actionpack', '= 2.0.991' + PKG_BUILD)
|
||||
s.add_dependency('actionmailer', '= 2.0.991' + PKG_BUILD)
|
||||
s.add_dependency('activeresource', '= 2.0.991' + PKG_BUILD)
|
||||
|
||||
s.rdoc_options << '--exclude' << '.'
|
||||
s.has_rdoc = false
|
||||
|
|
2
railties/html/javascripts/controls.js
vendored
2
railties/html/javascripts/controls.js
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
||||
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
|
||||
// Contributors:
|
||||
|
|
2
railties/html/javascripts/dragdrop.js
vendored
2
railties/html/javascripts/dragdrop.js
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
|
|
2
railties/html/javascripts/effects.js
vendored
2
railties/html/javascripts/effects.js
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Contributors:
|
||||
// Justin Palmer (http://encytemedia.com/)
|
||||
// Mark Pilgrim (http://diveintomark.org/)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'erb'
|
||||
require 'yaml'
|
||||
require 'optparse'
|
||||
|
||||
|
@ -8,7 +9,7 @@ OptionParser.new do |opt|
|
|||
end
|
||||
|
||||
env = ARGV.first || ENV['RAILS_ENV'] || 'development'
|
||||
unless config = YAML.load_file(RAILS_ROOT + "/config/database.yml")[env]
|
||||
unless config = YAML::load(ERB.new(IO.read(RAILS_ROOT + "/config/database.yml")).result)[env]
|
||||
abort "No database is configured for the environment '#{env}'"
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#--
|
||||
# Copyright (c) 2004-2007 David Heinemeier Hansson
|
||||
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -2,7 +2,7 @@ module Rails
|
|||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 0
|
||||
TINY = 2
|
||||
TINY = 991
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase
|
|||
m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
|
||||
m.class_collisions(class_path, "#{class_name}")
|
||||
|
||||
# Controller, helper, views, and test directories.
|
||||
# Controller, helper, views, test and stylesheets directories.
|
||||
m.directory(File.join('app/models', class_path))
|
||||
m.directory(File.join('app/controllers', controller_class_path))
|
||||
m.directory(File.join('app/helpers', controller_class_path))
|
||||
|
@ -42,6 +42,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase
|
|||
m.directory(File.join('app/views/layouts', controller_class_path))
|
||||
m.directory(File.join('test/functional', controller_class_path))
|
||||
m.directory(File.join('test/unit', class_path))
|
||||
m.directory(File.join('public/stylesheets', class_path))
|
||||
|
||||
for action in scaffold_views
|
||||
m.template(
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace :db do
|
|||
when 'postgresql'
|
||||
@encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
|
||||
begin
|
||||
ActiveRecord::Base.establish_connection(config.merge('database' => 'template1'))
|
||||
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres'))
|
||||
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
|
||||
ActiveRecord::Base.establish_connection(config)
|
||||
rescue
|
||||
|
@ -368,7 +368,7 @@ def drop_database(config)
|
|||
when /^sqlite/
|
||||
FileUtils.rm(File.join(RAILS_ROOT, config['database']))
|
||||
when 'postgresql'
|
||||
ActiveRecord::Base.establish_connection(config.merge('database' => 'template1'))
|
||||
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres'))
|
||||
ActiveRecord::Base.connection.drop_database config['database']
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue