diff --git a/tracks/app/controllers/application.rb b/tracks/app/controllers/application.rb index a22e5818..e040795a 100644 --- a/tracks/app/controllers/application.rb +++ b/tracks/app/controllers/application.rb @@ -90,8 +90,8 @@ class ApplicationController < ActionController::Base def init_not_done_counts(parents = ['project','context']) parents.each {|parent| - eval("@#{parent}_not_done_counts = Todo.count(:todo, - :conditions => ['todos.user_id = ? and todos.type = ? and todos.done = ?', @user.id, \"Immediate\", false], + eval("@#{parent}_not_done_counts = Todo.count(:all, + :conditions => ['user_id = ? and type = ? and done = ?', @user.id, \"Immediate\", false], :group => :#{parent}_id)") } end diff --git a/tracks/script/process/spinner b/tracks/script/process/spinner deleted file mode 100755 index 6816b32e..00000000 --- a/tracks/script/process/spinner +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../config/boot' -require 'commands/process/spinner' diff --git a/tracks/vendor/rails/actionmailer/CHANGELOG b/tracks/vendor/rails/actionmailer/CHANGELOG index 2ceba66d..d7c11e79 100644 --- a/tracks/vendor/rails/actionmailer/CHANGELOG +++ b/tracks/vendor/rails/actionmailer/CHANGELOG @@ -1,3 +1,22 @@ +*1.2.4* (August 8th, 2006) + +* Backport of documentation enhancements. [Kevin Clark, Marcel Molina Jr] + +* Correct spurious documentation example code which results in a SyntaxError. [Marcel Molina Jr.] + +* Mailer template root applies to a class and its subclasses rather than acting globally. #5555 [somekool@gmail.com] + + +*1.2.3* (June 29th, 2006) + +* Depend on Action Pack 1.12.3 + + +*1.2.2* (June 27th, 2006) + +* Depend on Action Pack 1.12.2 + + *1.2.1* (April 6th, 2005) * Be part of Rails 1.1.1 diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/base.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/base.rb index 96a6db64..a67072a9 100644 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/base.rb +++ b/tracks/vendor/rails/actionmailer/lib/action_mailer/base.rb @@ -5,20 +5,92 @@ require 'action_mailer/utils' require 'tmail/net' module ActionMailer #:nodoc: - # Usage: + # ActionMailer allows you to send email from your application using a mailer model and views. # - # class ApplicationMailer < ActionMailer::Base - # # Set up properties - # # Properties can also be specified via accessor methods - # # (i.e. self.subject = "foo") and instance variables (@subject = "foo"). + # = Mailer Models + # To use ActionMailer, you need to create a mailer model. + # + # $ script/generate mailer Notifier + # + # The generated model inherits from ActionMailer::Base. Emails are defined by creating methods within the model which are then + # used to set variables to be used in the mail template, to change options on the mail, or + # to add attachments. + # + # Examples: + # + # class Notifier < ActionMailer::Base + # def signup_notification(recipient) + # recipients recipient.email_address_with_name + # from "system@example.com" + # subject "New account information" + # body "account" => recipient + # end + # end + # + # Mailer methods have the following configuration methods available. + # + # * recipients - Takes one or more email addresses. These addresses are where your email will be delivered to. Sets the To: header. + # * subject - The subject of your email. Sets the Subject: header. + # * from - Who the email you are sending is from. Sets the From: header. + # * cc - Takes one or more email addresses. These addresses will receive a carbon copy of your email. Sets the Cc: header. + # * bcc - Takes one or more email address. These addresses will receive a blind carbon copy of your email. Sets the Bcc header. + # * sent_on - The date on which the message was sent. If not set, the header wil be set by the delivery agent. + # * content_type - Specify the content type of the message. Defaults to text/plain. + # * headers - Specify additional headers to be set for the message, e.g. headers 'X-Mail-Count' => 107370. + # + # The body method has special behavior. It takes a hash which generates an instance variable + # named after each key in the hash containing the value that that key points to. + # + # So, for example, body "account" => recipient would result + # in an instance variable @account with the value of recipient being accessible in the + # view. + # + # = Mailer Views + # Like ActionController, each mailer class has a corresponding view directory + # in which each method of the class looks for a template with its name. + # To define a template to be used with a mailing, create an .rhtml file with the same name as the method + # in your mailer model. For example, in the mailer defined above, the template at + # app/views/notifier/signup_notification.rhtml would be used to generate the email. + # + # Variables defined in the model are accessible as instance variables in the view. + # + # Emails by default are sent in plain text, so a sample view for our model example might look like this: + # + # Hi <%= @account.name %>, + # Thanks for joining our service! Please check back often. + # + # = Sending Mail + # Once a mailer action and template are defined, you can deliver your message or create it and save it + # for delivery later: + # + # Notifier.deliver_signup_notification(david) # sends the email + # mail = Notifier.create_signup_notification(david) # => a tmail object + # Notifier.deliver(mail) + # + # You never instantiate your mailer class. Rather, your delivery instance + # methods are automatically wrapped in class methods that start with the word + # deliver_ followed by the name of the mailer method that you would + # like to deliver. The signup_notification method defined above is + # delivered by invoking Notifier.deliver_signup_notification. + # + # = HTML Email + # To send mail as HTML, make sure your view (the .rhtml file) generates HTML and + # set the content type to html. + # + # class MyMailer < ActionMailer::Base # def signup_notification(recipient) # recipients recipient.email_address_with_name # subject "New account information" - # body { "account" => recipient } + # body "account" => recipient # from "system@example.com" + # content_type "text/html" # Here's where the magic happens # end + # end # - # # explicitly specify multipart messages + # = Multipart Email + # You can explicitly specify multipart messages: + # + # class ApplicationMailer < ActionMailer::Base # def signup_notification(recipient) # recipients recipient.email_address_with_name # subject "New account information" @@ -32,7 +104,28 @@ module ActionMailer #:nodoc: # p.transfer_encoding = "base64" # end # end + # end + # + # Multipart messages can also be used implicitly because ActionMailer will automatically + # detect and use multipart templates, where each template is named after the name of the action, followed + # by the content type. Each such detected template will be added as separate part to the message. + # + # For example, if the following templates existed: + # * signup_notification.text.plain.rhtml + # * signup_notification.text.html.rhtml + # * signup_notification.text.xml.rxml + # * signup_notification.text.x-yaml.rhtml + # + # Each would be rendered and added as a separate part to the message, + # with the corresponding content type. The same body hash is passed to + # each template. # + # = Attachments + # Attachments can be added by using the +attachment+ method. + # + # Example: + # + # class ApplicationMailer < ActionMailer::Base # # attachments # def signup_notification(recipient) # recipients recipient.email_address_with_name @@ -46,36 +139,7 @@ module ActionMailer #:nodoc: # a.body = generate_your_pdf_here() # end # end - # - # # implicitly multipart messages - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # from "system@example.com" - # body(:account => "recipient") - # - # # ActionMailer will automatically detect and use multipart templates, - # # where each template is named after the name of the action, followed - # # by the content type. Each such detected template will be added as - # # a separate part to the message. - # # - # # for example, if the following templates existed: - # # * signup_notification.text.plain.rhtml - # # * signup_notification.text.html.rhtml - # # * signup_notification.text.xml.rxml - # # * signup_notification.text.x-yaml.rhtml - # # - # # Each would be rendered and added as a separate part to the message, - # # with the corresponding content type. The same body hash is passed to - # # each template. - # end - # end - # - # # After this, post_notification will look for "templates/application_mailer/post_notification.rhtml" - # ApplicationMailer.template_root = "templates" - # - # ApplicationMailer.create_comment_notification(david, hello_world) # => a tmail object - # ApplicationMailer.deliver_comment_notification(david, hello_world) # sends the email + # end # # = Configuration options # @@ -127,7 +191,7 @@ module ActionMailer #:nodoc: private_class_method :new #:nodoc: - cattr_accessor :template_root + class_inheritable_accessor :template_root cattr_accessor :logger @@server_settings = { diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/version.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/version.rb index ba6a301c..8ecf6509 100644 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/version.rb +++ b/tracks/vendor/rails/actionmailer/lib/action_mailer/version.rb @@ -2,7 +2,7 @@ module ActionMailer module VERSION #:nodoc: MAJOR = 1 MINOR = 2 - TINY = 1 + TINY = 4 STRING = [MAJOR, MINOR, TINY].join('.') end diff --git a/tracks/vendor/rails/actionmailer/rakefile b/tracks/vendor/rails/actionmailer/rakefile index 3cf143b1..df1dd144 100644 --- a/tracks/vendor/rails/actionmailer/rakefile +++ b/tracks/vendor/rails/actionmailer/rakefile @@ -54,14 +54,14 @@ spec = Gem::Specification.new do |s| s.rubyforge_project = "actionmailer" s.homepage = "http://www.rubyonrails.org" - s.add_dependency('actionpack', '= 1.12.1' + PKG_BUILD) + s.add_dependency('actionpack', '= 1.12.4' + PKG_BUILD) s.has_rdoc = true s.requirements << 'none' s.require_path = 'lib' s.autorequire = 'action_mailer' - s.files = [ "rakefile", "install.rb", "README", "CHANGELOG", "MIT-LICENSE" ] + s.files = [ "Rakefile", "install.rb", "README", "CHANGELOG", "MIT-LICENSE" ] s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) } s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) } end @@ -84,116 +84,12 @@ task :pdoc => [:rdoc] do end desc "Publish the release files to RubyForge." -task :release => [:package] do - files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } +task :release => [ :package ] do + `rubyforge login` - if RUBY_FORGE_PROJECT then - require 'net/http' - require 'open-uri' - - project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" - project_data = open(project_uri) { |data| data.read } - group_id = project_data[/[?&]group_id=(\d+)/, 1] - raise "Couldn't get group id" unless group_id - - # This echos password to shell which is a bit sucky - if ENV["RUBY_FORGE_PASSWORD"] - password = ENV["RUBY_FORGE_PASSWORD"] - else - print "#{RUBY_FORGE_USER}@rubyforge.org's password: " - password = STDIN.gets.chomp - end - - login_response = Net::HTTP.start("rubyforge.org", 80) do |http| - data = [ - "login=1", - "form_loginname=#{RUBY_FORGE_USER}", - "form_pw=#{password}" - ].join("&") - http.post("/account/login.php", data) - end - - cookie = login_response["set-cookie"] - raise "Login failed" unless cookie - headers = { "Cookie" => cookie } - - release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" - release_data = open(release_uri, headers) { |data| data.read } - package_id = release_data[/[?&]package_id=(\d+)/, 1] - raise "Couldn't get package id" unless package_id - - first_file = true - release_id = "" - - files.each do |filename| - basename = File.basename(filename) - file_ext = File.extname(filename) - file_data = File.open(filename, "rb") { |file| file.read } - - puts "Releasing #{basename}..." - - release_response = Net::HTTP.start("rubyforge.org", 80) do |http| - release_date = Time.now.strftime("%Y-%m-%d %H:%M") - type_map = { - ".zip" => "3000", - ".tgz" => "3110", - ".gz" => "3110", - ".gem" => "1400" - }; type_map.default = "9999" - type = type_map[file_ext] - boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" - - query_hash = if first_file then - { - "group_id" => group_id, - "package_id" => package_id, - "release_name" => RELEASE_NAME, - "release_date" => release_date, - "type_id" => type, - "processor_id" => "8000", # Any - "release_notes" => "", - "release_changes" => "", - "preformatted" => "1", - "submit" => "1" - } - else - { - "group_id" => group_id, - "release_id" => release_id, - "package_id" => package_id, - "step2" => "1", - "type_id" => type, - "processor_id" => "8000", # Any - "submit" => "Add This File" - } - end - - query = "?" + query_hash.map do |(name, value)| - [name, URI.encode(value)].join("=") - end.join("&") - - data = [ - "--" + boundary, - "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", - "Content-Type: application/octet-stream", - "Content-Transfer-Encoding: binary", - "", file_data, "" - ].join("\x0D\x0A") - - release_headers = headers.merge( - "Content-Type" => "multipart/form-data; boundary=#{boundary}" - ) - - target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" - http.post(target + query, data, release_headers) - end - - if first_file then - release_id = release_response.body[/release_id=(\d+)/, 1] - raise("Couldn't get release id") unless release_id - end - - first_file = false - end + for ext in %w( gem tgz zip ) + release_command = "rubyforge add_release #{PKG_NAME} #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" + puts release_command + system(release_command) end -end +end \ No newline at end of file diff --git a/tracks/vendor/rails/actionmailer/test/mail_service_test.rb b/tracks/vendor/rails/actionmailer/test/mail_service_test.rb index c810cf10..5fdf4074 100644 --- a/tracks/vendor/rails/actionmailer/test/mail_service_test.rb +++ b/tracks/vendor/rails/actionmailer/test/mail_service_test.rb @@ -24,6 +24,8 @@ class Net::SMTP end class FunkyPathMailer < ActionMailer::Base + self.template_root = "#{File.dirname(__FILE__)}/fixtures/path.with.dots" + def multipart_with_template_path_with_dots(recipient) recipients recipient subject "Have a lovely picture" @@ -816,3 +818,15 @@ EOF end end +class InheritableTemplateRootTest < Test::Unit::TestCase + def test_attr + expected = "#{File.dirname(__FILE__)}/fixtures/path.with.dots" + assert_equal expected, FunkyPathMailer.template_root + + sub = Class.new(FunkyPathMailer) + sub.template_root = 'test/path' + + assert_equal 'test/path', sub.template_root + assert_equal expected, FunkyPathMailer.template_root + end +end diff --git a/tracks/vendor/rails/actionpack/CHANGELOG b/tracks/vendor/rails/actionpack/CHANGELOG index e332c9b1..61eedcd9 100644 --- a/tracks/vendor/rails/actionpack/CHANGELOG +++ b/tracks/vendor/rails/actionpack/CHANGELOG @@ -1,4 +1,55 @@ -*1.12.1* (April 6th, 2005) +*1.12.4* (August 8th, 2006) + +* Documentation fix: integration test scripts don't require integration_test. #4914 [Frederick Ros ] + +* ActionController::Base Summary documentation rewrite. #4900 [kevin.clark@gmail.com] + +* Fix text_helper.rb documentation rendering. #4725 [Frederick Ros] + +* Fixes bad rendering of JavaScriptMacrosHelper rdoc. #4910 [Frederick Ros] + +* Enhance documentation for setting headers in integration tests. Skip auto HTTP prepending when its already there. #4079 [Rick Olson] + +* Documentation for AbstractRequest. #4895 [kevin.clark@gmail.com] + +* Remove all remaining references to @params in the documentation. [Marcel Molina Jr.] + +* Add documentation for redirect_to :back's RedirectBackError exception. [Marcel Molina Jr.] + +* Update layout and content_for documentation to use yield rather than magic @content_for instance variables. [Marcel Molina Jr.] + +* Cache CgiRequest#request_parameters so that multiple calls don't re-parse multipart data. [Rick] + +* Fixed that remote_form_for can leave out the object parameter and default to the instance variable of the object_name, just like form_for [DHH] + +* Added ActionController.filter_parameter_logging that makes it easy to remove passwords, credit card numbers, and other sensitive information from being logged when a request is handled. #1897 [jeremye@bsa.ca.gov] + +* Fixed that real files and symlinks should be treated the same when compiling templates. #5438 [zachary@panandscan.com] + +* Add :status option to send_data and send_file. Defaults to '200 OK'. #5243 [Manfred Stienstra ] + +* Update documentation for erb trim syntax. #5651 [matt@mattmargolis.net] + +* Short documentation to mention use of Mime::Type.register. #5710 [choonkeat@gmail.com] + + +*1.12.3* (June 28th, 2006) + +* Fix broken traverse_to_controller. We now: + Look for a _controller.rb file under RAILS_ROOT to load. + If we find it, we require_dependency it and return the controller it defined. (If none was defined we stop looking.) + If we don't find it, we look for a .rb file under RAILS_ROOT to load. If we find it, and it loads a constant we keep looking. + Otherwise we check to see if a directory of the same name exists, and if it does we create a module for it. + + +*1.12.2* (June 27th, 2006) + +* Refinement to avoid exceptions in traverse_to_controller. + +* (Hackish) Fix loading of arbitrary files in Ruby's load path by traverse_to_controller. [Nicholas Seckar] + + +*1.12.1* (April 6th, 2006) * Fixed that template extensions would be cached development mode #4624 [Stefan Kaes] @@ -30,7 +81,7 @@ This can be used by deployment managers to set the asset id by application revision -*1.12.0* (March 27th, 2005) +*1.12.0* (March 27th, 2006) * Add documentation for respond_to. [Jamis Buck] diff --git a/tracks/vendor/rails/actionpack/README b/tracks/vendor/rails/actionpack/README index dc475a66..13ea9d1e 100644 --- a/tracks/vendor/rails/actionpack/README +++ b/tracks/vendor/rails/actionpack/README @@ -469,3 +469,7 @@ And as Jim from Rake says: For other information, feel free to ask on the ruby-talk mailing list (which is mirrored to comp.lang.ruby) or contact mailto:david@loudthinking.com. + + + +... diff --git a/tracks/vendor/rails/actionpack/filler b/tracks/vendor/rails/actionpack/filler new file mode 100644 index 00000000..1750e50e --- /dev/null +++ b/tracks/vendor/rails/actionpack/filler @@ -0,0 +1,53 @@ +this is just a filler file to try and work around the zlib error when unpacking the gem. Please ignore it, thanks. + +abcDEfgHijkLMNopqrStUVWxyz +AbcdefgHIjklMnOpqrsTUvwxYZ +AbCDEfghIjKLmnoPQrstuVwxyz +abcDefGhijKlmnopQrstuvWXYz +AbCdefGhiJKlmnoPqrstuVwxYz +aBcdefGHijKlmnOpQrStUvwxYz +AbcdEfGhIJklmnOPQrSTuvwxyZ +AbcDeFGHijkLmnopqrstuVwxYZ +ABcdefgHIjkLmnOpqrStuVwxyZ +aBcdEFGhiJklmnopQrstuVwxyz +abcDefgHijKlmnoPQrSTuvwxYz +AbcdefGhiJklmnOpqrstuVwxYZ +abcdefgHIjKlMNoPqRsTuvwxYz +ABcDeFghIjklMnopQrstUVwxyZ +AbcdefGhijkLmNopQRstuVWxYZ +aBcdefGhijklMNOpqRsTUvwxyz +abcdEFGhiJKlmnOPQrStUVwxyz +abcDefghIJklmnOPqRStuVWxyz +abcdefGhIjklmnoPQrStUVwXyZ +abcDefghIjkLmnopQrstuVwxyz +AbcdefGhIjklMNOPqrstuvWXyz +AbCdEfGHijkLmnopqrstuvwxyz +abCdEFghijKlmnopqRstuvwXYz +abCdEfghIJklmnOPqrsTUvwxyz +AbcdeFghijklmnoPqrStUvWxyZ +aBcDEFghIJKlmnopqrstuvWXyz +abcdEfghiJKlmNopqrstuvwXyz +AbcdEFGHIJKlmnopqRsTuvwxYz +abcdeFgHiJklmnoPQRsTuvwXYz +abcdEfGhijkLmnOPqrstUvwXYZ +abCDeFGhijklmNopQrstUvwxYz +abCdeFGhIjklmnOpQrstUvwxyZ +aBcDEFgHijKlmNOPQrsTUvwxYz +aBcDefghijklmNoPqrstUvWXyz +AbcDefgHiJklmnOPqRStuvwxYz +aBcdefGHijklMnopqRstUvwxyz +AbCdefghijKLmnopqRstuvWXyz +aBCdefGhiJkLMnopQrsTUvwxyz +ABcdefGHijKlmnOPqrSTUvWXyz +aBCdEfGHIJklMnopqRsTUvWxyz +ABcDEFGHIJklMnopqrSTuVwxyz +abcdEfghijklMnopqrstuvwxyz +AbCDEFghIjkLmNOpQRstUVwxyZ +abCdEFghIJklMNOPqrstUvwXYZ +abCdefghijklmnoPQrstuVwxyz +AbcdEfghijkLMnopqRSTUvWxYz +ABcDEfGhIjKLmNopqrStuVwxyZ +abCdefgHijklmnOpQRStuvwxYz +abCdeFghijKLmNopQrstuvwxyZ +abcdEFGHijKlmnopqrstuvwxYZ + diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/base.rb b/tracks/vendor/rails/actionpack/lib/action_controller/base.rb index 751f364a..37b98be9 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/base.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/base.rb @@ -49,13 +49,15 @@ module ActionController #:nodoc: end end - # Action Controllers are made up of one or more actions that performs its purpose and then either renders a template or - # redirects to another action. An action is defined as a public method on the controller, which will automatically be - # made accessible to the web-server through a mod_rewrite mapping. A sample controller could look like this: + # Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed + # on request and then either render a template or redirect to another action. An action is defined as a public method + # on the controller, which will automatically be made accessible to the web-server through Rails Routes. + # + # A sample controller could look like this: # # class GuestBookController < ActionController::Base # def index - # @entries = Entry.find_all + # @entries = Entry.find(:all) # end # # def sign @@ -64,26 +66,17 @@ module ActionController #:nodoc: # end # end # - # GuestBookController.template_root = "templates/" - # GuestBookController.process_cgi + # Actions, by default, render a template in the app/views directory corresponding to the name of the controller and action + # after executing code in the action. For example, the +index+ action of the +GuestBookController+ would render the + # template app/views/guestbook/index.rhtml by default after populating the @entries instance variable. # - # All actions assume that you want to render a template matching the name of the action at the end of the performance - # unless you tell it otherwise. The index action complies with this assumption, so after populating the @entries instance - # variable, the GuestBookController will render "templates/guestbook/index.rhtml". - # - # Unlike index, the sign action isn't interested in rendering a template. So after performing its main purpose (creating a - # new entry in the guest book), it sheds the rendering assumption and initiates a redirect instead. This redirect works by - # returning an external "302 Moved" HTTP response that takes the user to the index action. + # Unlike index, the sign action will not render a template. After performing its main purpose (creating a + # new entry in the guest book), it initiates a redirect instead. This redirect works by returning an external + # "302 Moved" HTTP response that takes the user to the index action. # # The index and sign represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect. # Most actions are variations of these themes. # - # Also note that it's the final call to process_cgi that actually initiates the action performance. It will extract - # request and response objects from the CGI - # - # When Action Pack is used inside of Rails, the template_root is automatically configured and you don't need to call process_cgi - # yourself. - # # == Requests # # Requests are processed by the Action Controller framework by extracting the value of the "action" key in the request parameters. @@ -94,16 +87,16 @@ module ActionController #:nodoc: # The full request object is available with the request accessor and is primarily used to query for http headers. These queries # are made by accessing the environment hash, like this: # - # def hello_ip - # location = request.env["REMOTE_IP"] - # render :text => "Hello stranger from #{location}" + # def server_ip + # location = request.env["SERVER_ADDR"] + # render :text => "This server hosted at #{location}" # end # # == Parameters # - # All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params hash. - # So an action that was performed through /weblog/list?category=All&limit=5 will include { "category" => "All", "limit" => 5 } - # in params. + # All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method + # which returns a hash. For example, an action that was performed through /weblog/list?category=All&limit=5 will include + # { "category" => "All", "limit" => 5 } in params. # # It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as: # @@ -116,12 +109,12 @@ module ActionController #:nodoc: # # == Sessions # - # Sessions allows you to store objects in memory between requests. This is useful for objects that are not yet ready to be persisted, + # Sessions allows you to store objects in between requests. This is useful for objects that are not yet ready to be persisted, # such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such # as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely # they could be changed unknowingly. It's usually too much work to keep it all synchronized -- something databases already excel at. # - # You can place objects in the session by using the session hash accessor: + # You can place objects in the session by using the session method, which accesses a hash: # # session[:person] = Person.authenticate(user_name, password) # @@ -129,17 +122,24 @@ module ActionController #:nodoc: # # Hello #{session[:person]} # - # Any object can be placed in the session (as long as it can be Marshalled). But remember that 1000 active sessions each storing a - # 50kb object could lead to a 50MB memory overhead. In other words, think carefully about size and caching before resorting to the use - # of the session. - # # For removing objects from the session, you can either assign a single key to nil, like session[:person] = nil, or you can # remove the entire session with reset_session. # + # By default, sessions are stored on the file system in RAILS_ROOT/tmp/sessions. Any object can be placed in the session + # (as long as it can be Marshalled). But remember that 1000 active sessions each storing a 50kb object could lead to a 50MB store on the filesystem. + # In other words, think carefully about size and caching before resorting to the use of the session on the filesystem. + # + # An alternative to storing sessions on disk is to use ActiveRecordStore to store sessions in your database, which can solve problems + # caused by storing sessions in the file system and may speed up your application. To use ActiveRecordStore, uncomment the line: + # + # config.action_controller.session_store = :active_record_store + # + # in your environment.rb and run rake db:sessions:create. + # # == Responses # # Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response - # object is generated automatically through the use of renders and redirects, so it's normally nothing you'll need to be concerned about. + # object is generated automatically through the use of renders and redirects and requires no user intervention. # # == Renders # @@ -161,9 +161,9 @@ module ActionController #:nodoc: # def search # @results = Search.find(params[:query]) # case @results - # when 0 then render :action=> "no_results" - # when 1 then render :action=> "show" - # when 2..10 then render :action=> "show_many" + # when 0 then render :action => "no_results" + # when 1 then render :action => "show" + # when 2..10 then render :action => "show_many" # end # end # @@ -171,32 +171,21 @@ module ActionController #:nodoc: # # == Redirects # - # Redirecting is what actions that update the model do when they're done. The save_post method shouldn't be responsible for also - # showing the post once it's saved -- that's the job for show_post. So once save_post has completed its business, it'll - # redirect to show_post. All redirects are external, which means that when the user refreshes his browser, it's not going to save - # the post again, but rather just show it one more time. - # - # This sounds fairly simple, but the redirection is complicated by the quest for a phenomenon known as "pretty urls". Instead of accepting - # the dreadful being that is "weblog_controller?action=show&post_id=5", Action Controller goes out of its way to represent the former as - # "/weblog/show/5". And this is even the simple case. As an example of a more advanced pretty url consider - # "/library/books/ISBN/0743536703/show", which can be mapped to books_controller?action=show&type=ISBN&id=0743536703. - # - # Redirects work by rewriting the URL of the current action. So if the show action was called by "/library/books/ISBN/0743536703/show", - # we can redirect to an edit action simply by doing redirect_to(:action => "edit"), which could throw the user to - # "/library/books/ISBN/0743536703/edit". Naturally, you'll need to setup the routes configuration file to point to the proper controller - # and action in the first place, but once you have, it can be rewritten with ease. - # - # Let's consider a bunch of examples on how to go from "/clients/37signals/basecamp/project/dash" to somewhere else: + # Redirects are used to move from one action to another. For example, after a create action, which stores a blog entry to a database, + # we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're going to reuse (and redirect to) + # a show action that we'll assume has already been created. The code might look like this: # - # redirect_to(:action => "edit") => - # /clients/37signals/basecamp/project/dash - # - # redirect_to(:client_name => "nextangle", :project_name => "rails") => - # /clients/nextangle/rails/project/dash + # def create + # @entry = Entry.new(params[:entry]) + # if @entry.save + # # The entry was saved correctly, redirect to show + # redirect_to :action => 'show', :id => @entry.id + # else + # # things didn't go so well, do something else + # end + # end # - # Those redirects happen under the configuration of: - # - # map.connect 'clients/:client_name/:project_name/:controller/:action' + # In this case, after saving our new entry to the database, the user is redirected to the show method which is then executed. # # == Calling multiple redirects or renders # @@ -214,15 +203,6 @@ module ActionController #:nodoc: # render :action => "overthere" # won't be called unless monkeys is nil # end # - # == Environments - # - # Action Controller works out of the box with CGI, FastCGI, and mod_ruby. CGI and mod_ruby controllers are triggered just the same using: - # - # WeblogController.process_cgi - # - # FastCGI controllers are triggered using: - # - # FCGI.each_cgi{ |cgi| WeblogController.process_cgi(cgi) } class Base DEFAULT_RENDER_STATUS_CODE = "200 OK" @@ -263,10 +243,10 @@ module ActionController #:nodoc: # Modern REST web services often need to submit complex data to the web application. # The param_parsers hash lets you register handlers wich will process the http body and add parameters to the - # @params hash. These handlers are invoked for post and put requests. + # params hash. These handlers are invoked for post and put requests. # # By default application/xml is enabled. A XmlSimple class with the same param name as the root will be instanciated - # in the @params. This allows XML requests to mask themselves as regular form submissions, so you can have one + # in the params. This allows XML requests to mask themselves as regular form submissions, so you can have one # action serve both regular forms and web service requests. # # Example of doing your own parser for a custom content type: @@ -366,6 +346,53 @@ module ActionController #:nodoc: def hide_action(*names) write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect { |n| n.to_s }) end + + # Replace sensitive paramater data from the request log. + # Filters paramaters that have any of the arguments as a substring. + # Looks in all subhashes of the param hash for keys to filter. + # If a block is given, each key and value of the paramater hash and all + # subhashes is passed to it, the value or key + # can be replaced using String#replace or similar method. + # + # Examples: + # filter_parameter_logging + # => Does nothing, just slows the logging process down + # + # filter_parameter_logging :password + # => replaces the value to all keys matching /password/i with "[FILTERED]" + # + # filter_parameter_logging :foo, "bar" + # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]" + # + # filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i } + # => reverses the value to all keys matching /secret/i + # + # filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i } + # => reverses the value to all keys matching /secret/i, and + # replaces the value to all keys matching /foo|bar/i with "[FILTERED]" + def filter_parameter_logging(*filter_words, &block) + parameter_filter = Regexp.new(filter_words.collect{ |s| s.to_s }.join('|'), true) if filter_words.length > 0 + + define_method(:filter_parameters) do |unfiltered_parameters| + filtered_parameters = {} + + unfiltered_parameters.each do |key, value| + if key =~ parameter_filter + filtered_parameters[key] = '[FILTERED]' + elsif value.is_a?(Hash) + filtered_parameters[key] = filter_parameters(value) + elsif block_given? + key, value = key.dup, value.dup + yield key, value + filtered_parameters[key] = value + else + filtered_parameters[key] = value + end + end + + filtered_parameters + end + end end public @@ -803,6 +830,10 @@ module ActionController #:nodoc: # redirect_to :back # # The redirection happens as a "302 Moved" header. + # + # When using redirect_to :back, if there is no referrer, + # RedirectBackError will be raised. You may specify some fallback + # behavior for this case by rescueing RedirectBackError. def redirect_to(options = {}, *parameters_for_method_reference) #:doc: case options when %r{^\w+://.*} @@ -901,7 +932,7 @@ module ActionController #:nodoc: if logger logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]" logger.info " Session ID: #{@session.session_id}" if @session and @session.respond_to?(:session_id) - logger.info " Parameters: #{@params.inspect}" + logger.info " Parameters: #{respond_to?(:filter_parameters) ? filter_parameters(@params).inspect : @params.inspect}" end end diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/caching.rb b/tracks/vendor/rails/actionpack/lib/action_controller/caching.rb index 0cb70c86..91da89ad 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/caching.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/caching.rb @@ -38,9 +38,9 @@ module ActionController #:nodoc: # # class WeblogController < ActionController::Base # def update - # List.update(@params["list"]["id"], @params["list"]) - # expire_page :action => "show", :id => @params["list"]["id"] - # redirect_to :action => "show", :id => @params["list"]["id"] + # List.update(params[:list][:id], params[:list]) + # expire_page :action => "show", :id => params[:list][:id] + # redirect_to :action => "show", :id => params[:list][:id] # end # end # diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/cgi_process.rb b/tracks/vendor/rails/actionpack/lib/action_controller/cgi_process.rb index ce8acdf3..09a6000b 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/cgi_process.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/cgi_process.rb @@ -64,11 +64,12 @@ module ActionController #:nodoc: end def request_parameters - if ActionController::Base.param_parsers.has_key?(content_type) - CGIMethods.parse_formatted_request_parameters(content_type, @env['RAW_POST_DATA']) - else - CGIMethods.parse_request_parameters(@cgi.params) - end + @request_parameters ||= + if ActionController::Base.param_parsers.has_key?(content_type) + CGIMethods.parse_formatted_request_parameters(content_type, @env['RAW_POST_DATA']) + else + CGIMethods.parse_request_parameters(@cgi.params) + end end def cookies diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/integration.rb b/tracks/vendor/rails/actionpack/lib/action_controller/integration.rb index 33ec1a01..74817c4b 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/integration.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/integration.rb @@ -140,14 +140,18 @@ module ActionController # Performs a GET request with the given parameters. The parameters may # be +nil+, a Hash, or a string that is appropriately encoded - # (application/x-www-form-urlencoded or multipart/form-data). + # (application/x-www-form-urlencoded or multipart/form-data). The headers + # should be a hash. The keys will automatically be upcased, with the + # prefix 'HTTP_' added if needed. def get(path, parameters=nil, headers=nil) process :get, path, parameters, headers end # Performs a POST request with the given parameters. The parameters may # be +nil+, a Hash, or a string that is appropriately encoded - # (application/x-www-form-urlencoded or multipart/form-data). + # (application/x-www-form-urlencoded or multipart/form-data). The headers + # should be a hash. The keys will automatically be upcased, with the + # prefix 'HTTP_' added if needed. def post(path, parameters=nil, headers=nil) process :post, path, parameters, headers end @@ -155,7 +159,9 @@ module ActionController # Performs an XMLHttpRequest request with the given parameters, mimicing # the request environment created by the Prototype library. The parameters # may be +nil+, a Hash, or a string that is appropriately encoded - # (application/x-www-form-urlencoded or multipart/form-data). + # (application/x-www-form-urlencoded or multipart/form-data). The headers + # should be a hash. The keys will automatically be upcased, with the + # prefix 'HTTP_' added if needed. def xml_http_request(path, parameters=nil, headers=nil) headers = (headers || {}).merge("X-Requested-With" => "XMLHttpRequest") post(path, parameters, headers) @@ -218,7 +224,7 @@ module ActionController (headers || {}).each do |key, value| key = key.to_s.upcase.gsub(/-/, "_") - key = "HTTP_#{key}" unless env.has_key?(key) + key = "HTTP_#{key}" unless env.has_key?(key) || env =~ /^X|HTTP/ env[key] = value end @@ -341,7 +347,6 @@ module ActionController # using the get/post methods: # # require "#{File.dirname(__FILE__)}/test_helper" - # require "integration_test" # # class ExampleTest < ActionController::IntegrationTest # fixtures :people @@ -366,7 +371,6 @@ module ActionController # reference any named routes you happen to have defined! # # require "#{File.dirname(__FILE__)}/test_helper" - # require "integration_test" # # class AdvancedTest < ActionController::IntegrationTest # fixtures :people, :rooms diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/layout.rb b/tracks/vendor/rails/actionpack/lib/action_controller/layout.rb index 7ecff733..4e9e42d4 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/layout.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/layout.rb @@ -27,7 +27,7 @@ module ActionController #:nodoc: # that the header and footer are only mentioned in one place, like this: # # - # <%= @content_for_layout %> + # <%= yield %> # # # And then you have content pages that look like this: @@ -47,7 +47,7 @@ module ActionController #:nodoc: # references that won't materialize before rendering time: # #

<%= @page_title %>

- # <%= @content_for_layout %> + # <%= yield %> # # ...and content pages that fulfill these references _at_ rendering time: # @@ -159,10 +159,12 @@ module ActionController #:nodoc: # # As you can see, you pass the template as the first parameter, the status code as the second ("200" is OK), and the layout # as the third. + # + # NOTE: The old notation for rendering the view from a layout was to expose the magic @content_for_layout instance + # variable. The preferred notation now is to use yield, as documented above. module ClassMethods - # If a layout is specified, all actions rendered through render and render_action will have their result assigned - # to @content_for_layout, which can then be used by the layout to insert their contents with - # <%= @content_for_layout %>. This layout can itself depend on instance variables assigned during action + # If a layout is specified, all rendered actions will have their result rendered + # when the layoutyield's. This layout can itself depend on instance variables assigned during action # performance and have access to them as any normal template would. def layout(template_name, conditions = {}) add_layout_conditions(conditions) diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/mime_responds.rb b/tracks/vendor/rails/actionpack/lib/action_controller/mime_responds.rb index ff483789..555ffda1 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/mime_responds.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/mime_responds.rb @@ -92,6 +92,12 @@ module ActionController #:nodoc: # Note that you can define your own XML parameter parser which would allow you to describe multiple entities # in a single request (i.e., by wrapping them all in a single root note), but if you just go with the flow # and accept Rails' defaults, life will be much easier. + # + # If you need to use a MIME type which isn't supported by default, you can register your own handlers in + # environment.rb as follows. + # + # Mime::Type.register "image/jpg", :jpg + # def respond_to(*types, &block) raise ArgumentError, "respond_to takes either types or a block, never bot" unless types.any? ^ block block ||= lambda { |responder| types.each { |type| responder.send(type) } } @@ -160,4 +166,4 @@ module ActionController #:nodoc: end end end -end \ No newline at end of file +end diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/pagination.rb b/tracks/vendor/rails/actionpack/lib/action_controller/pagination.rb index 630b244a..a1053e65 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/pagination.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/pagination.rb @@ -31,7 +31,7 @@ module ActionController # instance variable, which is an ordered collection of model objects for the # current page (at most 20, sorted by last name and first name), and a # @person_pages Paginator instance. The current page is determined - # by the @params['page'] variable. + # by the params[:page] variable. # # ==== Pagination for a single action # @@ -47,7 +47,7 @@ module ActionController # ==== Custom/"classic" pagination # # def list - # @person_pages = Paginator.new self, Person.count, 10, @params['page'] + # @person_pages = Paginator.new self, Person.count, 10, params[:page] # @people = Person.find :all, :order => 'last_name, first_name', # :limit => @person_pages.items_per_page, # :offset => @person_pages.current.offset diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/request.rb b/tracks/vendor/rails/actionpack/lib/action_controller/request.rb index 76257c1d..86547919 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/request.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/request.rb @@ -1,5 +1,6 @@ module ActionController - # These methods are available in both the production and test Request objects. + # Subclassing AbstractRequest makes these methods available to the request objects used in production and testing, + # CgiRequest and TestRequest class AbstractRequest cattr_accessor :relative_url_root @@ -65,6 +66,7 @@ module ActionController end end + # Returns the accepted MIME type for the request def accepts @accepts ||= if @env['HTTP_ACCEPT'].to_s.strip.empty? @@ -202,15 +204,21 @@ module ActionController host + port_string end - def path_parameters=(parameters) + def path_parameters=(parameters) #:nodoc: @path_parameters = parameters @symbolized_path_parameters = @parameters = nil end - def symbolized_path_parameters + # The same as path_parameters with explicitly symbolized keys + def symbolized_path_parameters @symbolized_path_parameters ||= path_parameters.symbolize_keys end + # Returns a hash with the parameters used to form the path of the request + # + # Example: + # + # {:action => 'my_action', :controller => 'my_controller'} def path_parameters @path_parameters ||= {} end diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/routing.rb b/tracks/vendor/rails/actionpack/lib/action_controller/routing.rb index d6e287e0..ac40c63e 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/routing.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/routing.rb @@ -218,43 +218,81 @@ module ActionController expr = "::#{controller.split('/').collect {|c| c.camelize}.join('::')}Controller" g.result :controller, expr, true end - + + def file_kinds(kind) + ((@file_kinds ||= []) << kind).uniq! || @file_kinds + end + def traverse_to_controller(segments, start_at = 0) mod = ::Object length = segments.length index = start_at mod_name = controller_name = segment = nil - while index < length - return nil unless /^[A-Za-z][A-Za-z\d_]*$/ =~ (segment = segments[index]) + return nil unless /\A[A-Za-z][A-Za-z\d_]*\Z/ =~ (segment = segments[index]) index += 1 + file_kinds :app mod_name = segment.camelize controller_name = "#{mod_name}Controller" + path_suffix = File.join(segments[start_at..(index - 1)]) + next_mod = nil - begin - # We use eval instead of const_get to avoid obtaining values from parent modules. - controller = eval("mod::#{controller_name}", nil, __FILE__, __LINE__) - expected_name = "#{mod.name}::#{controller_name}" - - # Detect the case when const_get returns an object from a parent namespace. - if controller.is_a?(Class) && controller.ancestors.include?(ActionController::Base) && (mod == Object || controller.name == expected_name) - return controller, (index - start_at) + # If the controller is already present, or if we load it, return it. + if mod.const_defined?(controller_name) || attempt_load(mod, controller_name, path_suffix + "_controller") == :defined + controller = mod.const_get(controller_name) + return nil unless controller.is_a?(Class) && controller.ancestors.include?(ActionController::Base) # it's not really a controller? + return [controller, (index - start_at)] + end + + # No controller? Look for the module + if mod.const_defined? mod_name + next_mod = mod.send(:const_get, mod_name) + next_mod = nil unless next_mod.is_a?(Module) + else + # Try to load a file that defines the module we want. + case attempt_load(mod, mod_name, path_suffix) + when :defined then next_mod = mod.const_get mod_name + when :dir then # We didn't find a file, but there's a dir. + next_mod = Module.new # So create a module for the directory + mod.send :const_set, mod_name, next_mod + else + return nil end - rescue NameError => e - raise unless /^uninitialized constant .*#{controller_name}$/ =~ e.message end + mod = next_mod - begin - next_mod = eval("mod::#{mod_name}", nil, __FILE__, __LINE__) - # Check that we didn't get a module from a parent namespace - mod = (mod == Object || next_mod.name == "#{mod.name}::#{mod_name}") ? next_mod : nil - rescue NameError => e - raise unless /^uninitialized constant .*#{mod_name}$/ =~ e.message - end - - return nil unless mod + return nil unless mod && mod.is_a?(Module) end + nil + end + + protected + def safe_load_paths #:nodoc: + if defined?(RAILS_ROOT) + $LOAD_PATH.select do |base| + base = File.expand_path(base) + extended_root = File.expand_path(RAILS_ROOT) + base.match(/\A#{Regexp.escape(extended_root)}\/*#{file_kinds(:lib) * '|'}/) || base =~ %r{rails-[\d.]+/builtin} + end + else + $LOAD_PATH + end + end + + def attempt_load(mod, const_name, path) + has_dir = false + safe_load_paths.each do |load_path| + full_path = File.join(load_path, path) + file_path = full_path + '.rb' + if File.file?(file_path) # Found a .rb file? Load it up + require_dependency(file_path) + return :defined if mod.const_defined? const_name + else + has_dir ||= File.directory?(full_path) + end + end + return (has_dir ? :dir : nil) end end end diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/streaming.rb b/tracks/vendor/rails/actionpack/lib/action_controller/streaming.rb index 2c4e76f3..618888d0 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/streaming.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/streaming.rb @@ -14,7 +14,7 @@ module ActionController #:nodoc: # it feasible to send even large files. # # Be careful to sanitize the path parameter if it coming from a web - # page. send_file(@params['path']) allows a malicious user to + # page. send_file(params[:path]) allows a malicious user to # download any file on your server. # # Options: @@ -28,6 +28,7 @@ module ActionController #:nodoc: # or to read the entire file before sending (false). Defaults to true. # * :buffer_size - specifies size (in bytes) of the buffer used to stream the file. # Defaults to 4096. + # * :status - specifies the status code to send with the response. Defaults to '200 OK'. # # The default Content-Type and Content-Disposition headers are # set to download arbitrary binary files in as many browsers as @@ -37,9 +38,12 @@ module ActionController #:nodoc: # Simple download: # send_file '/path/to.zip' # - # Show a JPEG in browser: + # Show a JPEG in the browser: # send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline' # + # Show a 404 page in the browser: + # send_file '/path/to/404.html, :type => 'text/html; charset=utf-8', :status => 404 + # # Read about the other Content-* HTTP headers if you'd like to # provide the user with more information (such as Content-Description). # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11 @@ -61,7 +65,7 @@ module ActionController #:nodoc: @performed_render = false if options[:stream] - render :text => Proc.new { |response, output| + render :status => options[:status], :text => Proc.new { |response, output| logger.info "Streaming file #{path}" unless logger.nil? len = options[:buffer_size] || 4096 File.open(path, 'rb') do |file| @@ -81,7 +85,7 @@ module ActionController #:nodoc: } else logger.info "Sending file #{path}" unless logger.nil? - File.open(path, 'rb') { |file| render :text => file.read } + File.open(path, 'rb') { |file| render :status => options[:status], :text => file.read } end end @@ -93,6 +97,7 @@ module ActionController #:nodoc: # * :type - specifies an HTTP content type. # Defaults to 'application/octet-stream'. # * :disposition - specifies whether the file will be shown inline or downloaded. + # * :status - specifies the status code to send with the response. Defaults to '200 OK'. # Valid values are 'inline' and 'attachment' (default). # # Generic data download: @@ -109,7 +114,7 @@ module ActionController #:nodoc: logger.info "Sending data #{options[:filename]}" unless logger.nil? send_file_headers! options.merge(:length => data.size) @performed_render = false - render :text => data + render :status => options[:status], :text => data end private @@ -139,4 +144,4 @@ module ActionController #:nodoc: @headers['Cache-Control'] = 'private' if @headers['Cache-Control'] == 'no-cache' end end -end \ No newline at end of file +end diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/templates/scaffolds/layout.rhtml b/tracks/vendor/rails/actionpack/lib/action_controller/templates/scaffolds/layout.rhtml index 120f0cfb..759781e0 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/templates/scaffolds/layout.rhtml +++ b/tracks/vendor/rails/actionpack/lib/action_controller/templates/scaffolds/layout.rhtml @@ -63,7 +63,7 @@

<%= flash[:notice] %>

-<%= @content_for_layout %> +<%= yield %> diff --git a/tracks/vendor/rails/actionpack/lib/action_controller/verification.rb b/tracks/vendor/rails/actionpack/lib/action_controller/verification.rb index 0bef8d85..d78f5f06 100644 --- a/tracks/vendor/rails/actionpack/lib/action_controller/verification.rb +++ b/tracks/vendor/rails/actionpack/lib/action_controller/verification.rb @@ -37,7 +37,7 @@ module ActionController #:nodoc: # is a hash consisting of the following key/value pairs: # # * :params: a single key or an array of keys that must - # be in the @params hash in order for the action(s) to be safely + # be in the params hash in order for the action(s) to be safely # called. # * :session: a single key or an array of keys that must # be in the @session in order for the action(s) to be safely called. diff --git a/tracks/vendor/rails/actionpack/lib/action_pack/version.rb b/tracks/vendor/rails/actionpack/lib/action_pack/version.rb index 407e5480..6002b9c2 100644 --- a/tracks/vendor/rails/actionpack/lib/action_pack/version.rb +++ b/tracks/vendor/rails/actionpack/lib/action_pack/version.rb @@ -2,7 +2,7 @@ module ActionPack #:nodoc: module VERSION #:nodoc: MAJOR = 1 MINOR = 12 - TINY = 1 + TINY = 4 STRING = [MAJOR, MINOR, TINY].join('.') end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/base.rb b/tracks/vendor/rails/actionpack/lib/action_view/base.rb index 2ee4227a..1f156340 100644 --- a/tracks/vendor/rails/actionpack/lib/action_view/base.rb +++ b/tracks/vendor/rails/actionpack/lib/action_view/base.rb @@ -11,7 +11,7 @@ module ActionView #:nodoc: # # = ERb # - # You trigger ERb by using embeddings such as <% %> and <%= %>. The difference is whether you want output or not. Consider the + # You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the # following loop for names: # # Names of all the people @@ -19,12 +19,14 @@ module ActionView #:nodoc: # Name: <%= person.name %>
# <% end %> # - # The loop is setup in regular embedding tags (<% %>) and the name is written using the output embedding tag (<%= %>). Note that this + # The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this # is not just a usage suggestion. Regular output functions like print or puts won't work with ERb templates. So this would be wrong: # # Hi, Mr. <% puts "Frodo" %> # - # (If you absolutely must write from within a function, you can use the TextHelper#concat) + # If you absolutely must write from within a function, you can use the TextHelper#concat + # + # <%- and -%> suppress leading and trailing whitespace, including the trailing newline, and can be used interchangeably with <% and %>. # # == Using sub templates # @@ -425,7 +427,8 @@ module ActionView #:nodoc: if @@compile_time[render_symbol] && supports_local_assigns?(render_symbol, local_assigns) if file_name && !@@cache_template_loading - @@compile_time[render_symbol] < File.mtime(file_name) + @@compile_time[render_symbol] < File.mtime(file_name) || (File.symlink?(file_name) ? + @@compile_time[render_symbol] < File.lstat(file_name).mtime : false) end else true diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb index 9828fe0f..28b3e299 100644 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/tracks/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb @@ -1,6 +1,6 @@ module ActionView module Helpers - # Capture lets you extract parts of code into instance variables which + # Capture lets you extract parts of code which # can be used in other points of the template or even layout file. # # == Capturing a block into an instance variable @@ -8,12 +8,11 @@ module ActionView # <% @script = capture do %> # [some html...] # <% end %> - # # # == Add javascript to header using content_for # - # content_for("name") is a wrapper for capture which will store the - # fragment in a instance variable similar to @content_for_layout. + # content_for("name") is a wrapper for capture which will + # make the fragment available by name to a yielding layout or template. # # layout.rhtml: # @@ -21,11 +20,11 @@ module ActionView # # layout with js # + # <%= yield :script %> + # # # - # <%= @content_for_layout %> + # <%= yield %> # # # @@ -69,13 +68,9 @@ module ActionView end end - # Content_for will store the given block - # in an instance variable for later use in another template - # or in the layout. - # - # The name of the instance variable is content_for_ - # to stay consistent with @content_for_layout which is used - # by ActionView's layouts + # Calling content_for stores the block of markup for later use. + # Subsequently, you can make calls to it by name with yield + # in another template or in the layout. # # Example: # @@ -83,10 +78,17 @@ module ActionView # alert('hello world') # <% end %> # - # You can use @content_for_header anywhere in your templates. + # You can use yield :header anywhere in your templates. + # + # <%= yield :header %> # # NOTE: Beware that content_for is ignored in caches. So you shouldn't use it - # for elements that are going to be fragment cached. + # for elements that are going to be fragment cached. + # + # The deprecated way of accessing a content_for block was to use a instance variable + # named @@content_for_#{name_of_the_content_block}@. So <%= content_for('footer') %> + # would be avaiable as <%= @content_for_footer %>. The preferred notation now is + # <%= yield :footer %>. def content_for(name, &block) eval "@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)" end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb index 3e0b6942..53b39305 100644 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -310,7 +310,7 @@ module ActionView "select", add_options(options_from_collection_for_select(collection, value_method, text_method, value), options, value), html_options ) end - + def to_country_select_tag(priority_countries, options, html_options) html_options = html_options.stringify_keys add_default_name_and_id(html_options) diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb index fee8e125..2cb64c95 100644 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb +++ b/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb @@ -27,6 +27,7 @@ module ActionView # :url:: Specifies the url where the updated value should # be sent after the user presses "ok". # + # # Addtional +options+ are: # :rows:: Number of rows (more than 1 will use a TEXTAREA) # :cols:: Number of characters the text input should span (works for both INPUT and TEXTAREA) @@ -122,10 +123,10 @@ module ActionView # :on_show:: Like on_hide, only now the expression is called # then the div is shown. # :after_update_element:: A Javascript expression that is called when the - # user has selected one of the proposed values. - # The expression should take two variables: element and value. - # Element is a DOM element for the field, value - # is the value selected by the user. + # user has selected one of the proposed values. + # The expression should take two variables: element and value. + # Element is a DOM element for the field, value + # is the value selected by the user. # :select:: Pick the class of the element from which the value for # insertion should be extracted. If this is not specified, # the entire element is used. diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb index 1dee0f69..3c4c0ba9 100644 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/tracks/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -143,7 +143,7 @@ module ActionView # background instead of the regular reloading POST arrangement. Even # though it's using JavaScript to serialize the form elements, the form # submission will work just like a regular submission as viewed by the - # receiving side (all elements available in @params). The options for + # receiving side (all elements available in params). The options for # specifying the target with :url and defining callbacks is the same as # link_to_remote. # @@ -171,9 +171,10 @@ module ActionView end # Works like form_remote_tag, but uses form_for semantics. - def remote_form_for(object_name, object, options = {}, &proc) + def remote_form_for(object_name, *args, &proc) + options = args.last.is_a?(Hash) ? args.pop : {} concat(form_remote_tag(options), proc.binding) - fields_for(object_name, object, options, &proc) + fields_for(object_name, *(args << options), &proc) concat('', proc.binding) end alias_method :form_remote_for, :remote_form_for diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb index 80c80e31..a777c64e 100644 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb +++ b/tracks/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb @@ -77,7 +77,7 @@ module ActionView end begin - require_library_or_gem "redcloth" + require_library_or_gem "redcloth" unless Object.const_defined?(:RedCloth) # Returns the text with all the Textile codes turned into HTML-tags. # This method is only available if RedCloth can be required. @@ -104,7 +104,7 @@ module ActionView end begin - require_library_or_gem "bluecloth" + require_library_or_gem "bluecloth" unless Object.const_defined?(:BlueCloth) # Returns the text with all the Markdown codes turned into HTML-tags. # This method is only available if BlueCloth can be required. @@ -116,7 +116,7 @@ module ActionView end # Returns +text+ transformed into HTML using very simple formatting rules - # Surrounds paragraphs with <p> tags, and converts line breaks into <br /> + # Surrounds paragraphs with

tags, and converts line breaks into
# Two consecutive newlines(\n\n) are considered as a paragraph, one newline (\n) is # considered a linebreak, three or more consecutive newlines are turned into two newlines def simple_format(text) @@ -129,7 +129,7 @@ module ActionView end # Turns all urls and email addresses into clickable links. The +link+ parameter can limit what should be linked. - # Options are :all (default), :email_addresses, and :urls. + # Options are :all (default), :email_addresses, and :urls. # # Example: # auto_link("Go to http://www.rubyonrails.com and say hello to david@loudthinking.com") => @@ -235,28 +235,28 @@ module ActionView # array every time it is called. This can be used to alternate classes # for table rows: # - # <%- for item in @items do -%> - # "> - # ... use item ... - # - # <%- end -%> + # <%- for item in @items do -%> + # "> + # ... use item ... + # + # <%- end -%> # # You can use named cycles to prevent clashes in nested loops. You'll # have to reset the inner cycle, manually: # - # <%- for item in @items do -%> - # "row_class") - # - # <%- for value in item.values do -%> - # "colors") %>'"> - # item - # - # <%- end -%> - # <%- reset_cycle("colors") -%> - # - # - # <%- end -%> + # <%- for item in @items do -%> + # "row_class") + # + # <%- for value in item.values do -%> + # "colors") %>'"> + # item + # + # <%- end -%> + # <%- reset_cycle("colors") -%> + # + # + # <%- end -%> def cycle(first_value, *values) if (values.last.instance_of? Hash) params = values.pop diff --git a/tracks/vendor/rails/actionpack/rakefile b/tracks/vendor/rails/actionpack/rakefile index 2abdb816..7cf36692 100644 --- a/tracks/vendor/rails/actionpack/rakefile +++ b/tracks/vendor/rails/actionpack/rakefile @@ -46,8 +46,12 @@ Rake::RDocTask.new { |rdoc| rdoc.title = "Action Pack -- On rails from request to response" rdoc.options << '--line-numbers' << '--inline-source' rdoc.template = "#{ENV['template']}.rb" if ENV['template'] - rdoc.rdoc_files.include('README', 'RUNNING_UNIT_TESTS', 'CHANGELOG') - rdoc.rdoc_files.include('lib/**/*.rb') + if ENV['DOC_FILES'] + rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/)) + else + rdoc.rdoc_files.include('README', 'RUNNING_UNIT_TESTS', 'CHANGELOG') + rdoc.rdoc_files.include('lib/**/*.rb') + end } # Create compressed packages @@ -73,7 +77,7 @@ spec = Gem::Specification.new do |s| s.require_path = 'lib' s.autorequire = 'action_controller' - s.files = [ "rakefile", "install.rb", "README", "RUNNING_UNIT_TESTS", "CHANGELOG", "MIT-LICENSE", "examples/.htaccess" ] + s.files = [ "filler", "Rakefile", "install.rb", "README", "RUNNING_UNIT_TESTS", "CHANGELOG", "MIT-LICENSE", "examples/.htaccess" ] dist_dirs.each do |dir| s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) } end @@ -136,116 +140,12 @@ task :pdoc => [:rdoc] do end desc "Publish the release files to RubyForge." -task :release => [:package] do - files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } +task :release => [ :package ] do + `rubyforge login` - if RUBY_FORGE_PROJECT then - require 'net/http' - require 'open-uri' - - project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" - project_data = open(project_uri) { |data| data.read } - group_id = project_data[/[?&]group_id=(\d+)/, 1] - raise "Couldn't get group id" unless group_id - - # This echos password to shell which is a bit sucky - if ENV["RUBY_FORGE_PASSWORD"] - password = ENV["RUBY_FORGE_PASSWORD"] - else - print "#{RUBY_FORGE_USER}@rubyforge.org's password: " - password = STDIN.gets.chomp - end - - login_response = Net::HTTP.start("rubyforge.org", 80) do |http| - data = [ - "login=1", - "form_loginname=#{RUBY_FORGE_USER}", - "form_pw=#{password}" - ].join("&") - http.post("/account/login.php", data) - end - - cookie = login_response["set-cookie"] - raise "Login failed" unless cookie - headers = { "Cookie" => cookie } - - release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" - release_data = open(release_uri, headers) { |data| data.read } - package_id = release_data[/[?&]package_id=(\d+)/, 1] - raise "Couldn't get package id" unless package_id - - first_file = true - release_id = "" - - files.each do |filename| - basename = File.basename(filename) - file_ext = File.extname(filename) - file_data = File.open(filename, "rb") { |file| file.read } - - puts "Releasing #{basename}..." - - release_response = Net::HTTP.start("rubyforge.org", 80) do |http| - release_date = Time.now.strftime("%Y-%m-%d %H:%M") - type_map = { - ".zip" => "3000", - ".tgz" => "3110", - ".gz" => "3110", - ".gem" => "1400" - }; type_map.default = "9999" - type = type_map[file_ext] - boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" - - query_hash = if first_file then - { - "group_id" => group_id, - "package_id" => package_id, - "release_name" => RELEASE_NAME, - "release_date" => release_date, - "type_id" => type, - "processor_id" => "8000", # Any - "release_notes" => "", - "release_changes" => "", - "preformatted" => "1", - "submit" => "1" - } - else - { - "group_id" => group_id, - "release_id" => release_id, - "package_id" => package_id, - "step2" => "1", - "type_id" => type, - "processor_id" => "8000", # Any - "submit" => "Add This File" - } - end - - query = "?" + query_hash.map do |(name, value)| - [name, URI.encode(value)].join("=") - end.join("&") - - data = [ - "--" + boundary, - "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", - "Content-Type: application/octet-stream", - "Content-Transfer-Encoding: binary", - "", file_data, "" - ].join("\x0D\x0A") - - release_headers = headers.merge( - "Content-Type" => "multipart/form-data; boundary=#{boundary}" - ) - - target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" - http.post(target + query, data, release_headers) - end - - if first_file then - release_id = release_response.body[/release_id=(\d+)/, 1] - raise("Couldn't get release id") unless release_id - end - - first_file = false - end + for ext in %w( gem tgz zip ) + release_command = "rubyforge add_release #{PKG_NAME} #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" + puts release_command + system(release_command) end end diff --git a/tracks/vendor/rails/actionpack/test/controller/fake_controllers.rb b/tracks/vendor/rails/actionpack/test/controller/fake_controllers.rb index 5f958b28..f95339a2 100644 --- a/tracks/vendor/rails/actionpack/test/controller/fake_controllers.rb +++ b/tracks/vendor/rails/actionpack/test/controller/fake_controllers.rb @@ -6,6 +6,7 @@ class NotAController end module Admin class << self; alias_method :const_available?, :const_defined?; end + SomeConstant = 10 class UserController < Class.new(ActionController::Base); end class NewsFeedController < Class.new(ActionController::Base); end end diff --git a/tracks/vendor/rails/actionpack/test/controller/filter_params_test.rb b/tracks/vendor/rails/actionpack/test/controller/filter_params_test.rb new file mode 100644 index 00000000..5ad0d7f8 --- /dev/null +++ b/tracks/vendor/rails/actionpack/test/controller/filter_params_test.rb @@ -0,0 +1,42 @@ +require File.dirname(__FILE__) + '/../abstract_unit' + +class FilterParamController < ActionController::Base +end + +class FilterParamTest < Test::Unit::TestCase + def setup + @controller = FilterParamController.new + end + + def test_filter_parameters + assert FilterParamController.respond_to?(:filter_parameter_logging) + assert !@controller.respond_to?(:filter_parameters) + + FilterParamController.filter_parameter_logging + assert @controller.respond_to?(:filter_parameters) + + test_hashes = [[{},{},[]], + [{'foo'=>'bar'},{'foo'=>'bar'},[]], + [{'foo'=>'bar'},{'foo'=>'bar'},%w'food'], + [{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'], + [{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'], + [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'], + [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'], + [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana']] + + test_hashes.each do |before_filter, after_filter, filter_words| + FilterParamController.filter_parameter_logging(*filter_words) + assert_equal after_filter, @controller.filter_parameters(before_filter) + + filter_words.push('blah') + FilterParamController.filter_parameter_logging(*filter_words) do |key, value| + value.reverse! if key =~ /bargain/ + end + + before_filter['barg'] = {'bargain'=>'gain', 'blah'=>'bar', 'bar'=>{'bargain'=>{'blah'=>'foo'}}} + after_filter['barg'] = {'bargain'=>'niag', 'blah'=>'[FILTERED]', 'bar'=>{'bargain'=>{'blah'=>'[FILTERED]'}}} + + assert_equal after_filter, @controller.filter_parameters(before_filter) + end + end +end diff --git a/tracks/vendor/rails/actionpack/test/controller/routing_test.rb b/tracks/vendor/rails/actionpack/test/controller/routing_test.rb index b5709096..035b1b55 100644 --- a/tracks/vendor/rails/actionpack/test/controller/routing_test.rb +++ b/tracks/vendor/rails/actionpack/test/controller/routing_test.rb @@ -535,7 +535,6 @@ end class RouteTests < Test::Unit::TestCase - def route(*args) @route = ::ActionController::Routing::Route.new(*args) unless args.empty? return @route @@ -972,4 +971,79 @@ class RouteSetTests < Test::Unit::TestCase end end +class ControllerComponentTest < Test::Unit::TestCase + + def test_traverse_to_controller_should_not_load_arbitrary_files + load_path = $:.dup + base = File.dirname(File.dirname(File.expand_path(__FILE__))) + $: << File.join(base, 'fixtures') + Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root') + assert_equal nil, ActionController::Routing::ControllerComponent.traverse_to_controller(%w(dont_load pretty please)) + ensure + $:[0..-1] = load_path + Object.send :remove_const, :RAILS_ROOT + end + + def test_traverse_should_not_trip_on_non_module_constants + assert_equal nil, ActionController::Routing::ControllerComponent.traverse_to_controller(%w(admin some_constant a)) + end + + # This is evil, but people do it. + def test_traverse_to_controller_should_pass_thru_classes + load_path = $:.dup + base = File.dirname(File.dirname(File.expand_path(__FILE__))) + $: << File.join(base, 'fixtures') + $: << File.join(base, 'fixtures/application_root/app/controllers') + $: << File.join(base, 'fixtures/application_root/app/models') + Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root') + pair = ActionController::Routing::ControllerComponent.traverse_to_controller(%w(a_class_that_contains_a_controller poorly_placed)) + + # Make sure the container class was loaded properly + assert defined?(AClassThatContainsAController) + assert_kind_of Class, AClassThatContainsAController + assert_equal :you_know_it, AClassThatContainsAController.is_special? + + # Make sure the controller was too + assert_kind_of Array, pair + assert_equal 2, pair[1] + klass = pair.first + assert_kind_of Class, klass + assert_equal :decidedly_so, klass.is_evil? + assert klass.ancestors.include?(ActionController::Base) + assert defined?(AClassThatContainsAController::PoorlyPlacedController) + assert_equal klass, AClassThatContainsAController::PoorlyPlacedController + ensure + $:[0..-1] = load_path + Object.send :remove_const, :RAILS_ROOT + end + + def test_traverse_to_nested_controller + load_path = $:.dup + base = File.dirname(File.dirname(File.expand_path(__FILE__))) + $: << File.join(base, 'fixtures') + $: << File.join(base, 'fixtures/application_root/app/controllers') + Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root') + pair = ActionController::Routing::ControllerComponent.traverse_to_controller(%w(module_that_holds_controllers nested)) + + assert_not_equal nil, pair + + # Make sure that we created a module for the dir + assert defined?(ModuleThatHoldsControllers) + assert_kind_of Module, ModuleThatHoldsControllers + + # Make sure the controller is ok + assert_kind_of Array, pair + assert_equal 2, pair[1] + klass = pair.first + assert_kind_of Class, klass + assert klass.ancestors.include?(ActionController::Base) + assert defined?(ModuleThatHoldsControllers::NestedController) + assert_equal klass, ModuleThatHoldsControllers::NestedController + ensure + $:[0..-1] = load_path + Object.send :remove_const, :RAILS_ROOT + end + +end + end diff --git a/tracks/vendor/rails/actionpack/test/controller/send_file_test.rb b/tracks/vendor/rails/actionpack/test/controller/send_file_test.rb index 683d6eba..4c97e2d5 100644 --- a/tracks/vendor/rails/actionpack/test/controller/send_file_test.rb +++ b/tracks/vendor/rails/actionpack/test/controller/send_file_test.rb @@ -85,11 +85,25 @@ class SendFileTest < Test::Unit::TestCase assert_equal 'type', h['Content-Type'] assert_equal 'disposition; filename="filename"', h['Content-Disposition'] assert_equal 'binary', h['Content-Transfer-Encoding'] - + # test overriding Cache-Control: no-cache header to fix IE open/save dialog @controller.headers = { 'Cache-Control' => 'no-cache' } @controller.send(:send_file_headers!, options) h = @controller.headers assert_equal 'private', h['Cache-Control'] end + + %w(file data).each do |method| + define_method "test_send_#{method}_status" do + @controller.options = { :stream => false, :status => 500 } + assert_nothing_raised { assert_not_nil process(method) } + assert_equal '500', @controller.headers['Status'] + end + + define_method "test_default_send_#{method}_status" do + @controller.options = { :stream => false } + assert_nothing_raised { assert_not_nil process(method) } + assert_equal ActionController::Base::DEFAULT_RENDER_STATUS_CODE, @controller.headers['Status'] + end + end end diff --git a/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb b/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb new file mode 100644 index 00000000..11e48da8 --- /dev/null +++ b/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb @@ -0,0 +1,7 @@ +class AClassThatContainsAController::PoorlyPlacedController < ActionController::Base + + def self.is_evil? + :decidedly_so + end + +end \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb b/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb new file mode 100644 index 00000000..ea6abec2 --- /dev/null +++ b/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb @@ -0,0 +1,3 @@ +class ModuleThatHoldsControllers::NestedController < ActionController::Base + +end \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb b/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb new file mode 100644 index 00000000..598e54a1 --- /dev/null +++ b/tracks/vendor/rails/actionpack/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb @@ -0,0 +1,7 @@ +class AClassThatContainsAController #often < ActiveRecord::Base + + def self.is_special? + :you_know_it + end + +end \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/test/fixtures/dont_load.rb b/tracks/vendor/rails/actionpack/test/fixtures/dont_load.rb new file mode 100644 index 00000000..6a77d9f7 --- /dev/null +++ b/tracks/vendor/rails/actionpack/test/fixtures/dont_load.rb @@ -0,0 +1,3 @@ +# see routing/controller component tests + +raise Exception, "I should never be loaded" \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/test/template/compiled_templates_test.rb b/tracks/vendor/rails/actionpack/test/template/compiled_templates_test.rb new file mode 100644 index 00000000..3bb1e58c --- /dev/null +++ b/tracks/vendor/rails/actionpack/test/template/compiled_templates_test.rb @@ -0,0 +1,134 @@ +require 'test/unit' +require File.dirname(__FILE__) + '/../../lib/action_view/helpers/date_helper' +require File.dirname(__FILE__) + "/../abstract_unit" + +class CompiledTemplateTests < Test::Unit::TestCase + + def setup + @ct = ActionView::CompiledTemplates.new + @v = Class.new + @v.send :include, @ct + @a = './test_compile_template_a.rhtml' + @b = './test_compile_template_b.rhtml' + @s = './test_compile_template_link.rhtml' + end + def teardown + [@a, @b, @s].each do |f| + `rm #{f}` if File.exist?(f) || File.symlink?(f) + end + end + attr_reader :ct, :v + + def test_name_allocation + hi_world = ct.method_names['hi world'] + hi_sexy = ct.method_names['hi sexy'] + wish_upon_a_star = ct.method_names['I love seeing decent error messages'] + + assert_equal hi_world, ct.method_names['hi world'] + assert_equal hi_sexy, ct.method_names['hi sexy'] + assert_equal wish_upon_a_star, ct.method_names['I love seeing decent error messages'] + assert_equal 3, [hi_world, hi_sexy, wish_upon_a_star].uniq.length + end + + def test_wrap_source + assert_equal( + "def aliased_assignment(value)\nself.value = value\nend", + @ct.wrap_source(:aliased_assignment, [:value], 'self.value = value') + ) + + assert_equal( + "def simple()\nnil\nend", + @ct.wrap_source(:simple, [], 'nil') + ) + end + + def test_compile_source_single_method + selector = ct.compile_source('doubling method', [:a], 'a + a') + assert_equal 2, @v.new.send(selector, 1) + assert_equal 4, @v.new.send(selector, 2) + assert_equal -4, @v.new.send(selector, -2) + assert_equal 0, @v.new.send(selector, 0) + selector + end + + def test_compile_source_two_method + sel1 = test_compile_source_single_method # compile the method in the other test + sel2 = ct.compile_source('doubling method', [:a, :b], 'a + b + a + b') + assert_not_equal sel1, sel2 + + assert_equal 2, @v.new.send(sel1, 1) + assert_equal 4, @v.new.send(sel1, 2) + + assert_equal 6, @v.new.send(sel2, 1, 2) + assert_equal 32, @v.new.send(sel2, 15, 1) + end + + def test_mtime + t1 = Time.now + test_compile_source_single_method + assert (t1..Time.now).include?(ct.mtime('doubling method', [:a])) + end + + def test_compile_time + `echo '#{@a}' > #{@a}; echo '#{@b}' > #{@b}; ln -s #{@a} #{@s}` + + v = ActionView::Base.new + v.base_path = '.' + v.cache_template_loading = false; + + sleep 1 + t = Time.now + v.compile_and_render_template(:rhtml, '', @a) + v.compile_and_render_template(:rhtml, '', @b) + v.compile_and_render_template(:rhtml, '', @s) + a_n = v.method_names[@a] + b_n = v.method_names[@b] + s_n = v.method_names[@s] + # all of the files have changed since last compile + assert v.compile_time[a_n] > t + assert v.compile_time[b_n] > t + assert v.compile_time[s_n] > t + + sleep 1 + t = Time.now + v.compile_and_render_template(:rhtml, '', @a) + v.compile_and_render_template(:rhtml, '', @b) + v.compile_and_render_template(:rhtml, '', @s) + # none of the files have changed since last compile + assert v.compile_time[a_n] < t + assert v.compile_time[b_n] < t + assert v.compile_time[s_n] < t + + `rm #{@s}; ln -s #{@b} #{@s}` + v.compile_and_render_template(:rhtml, '', @a) + v.compile_and_render_template(:rhtml, '', @b) + v.compile_and_render_template(:rhtml, '', @s) + # the symlink has changed since last compile + assert v.compile_time[a_n] < t + assert v.compile_time[b_n] < t + assert v.compile_time[s_n] > t + + sleep 1 + `touch #{@b}` + t = Time.now + v.compile_and_render_template(:rhtml, '', @a) + v.compile_and_render_template(:rhtml, '', @b) + v.compile_and_render_template(:rhtml, '', @s) + # the file at the end of the symlink has changed since last compile + # both the symlink and the file at the end of it should be recompiled + assert v.compile_time[a_n] < t + assert v.compile_time[b_n] > t + assert v.compile_time[s_n] > t + end +end + +module ActionView + class Base + def compile_time + @@compile_time + end + def method_names + @@method_names + end + end +end diff --git a/tracks/vendor/rails/actionwebservice/CHANGELOG b/tracks/vendor/rails/actionwebservice/CHANGELOG index dd39728c..962bc635 100644 --- a/tracks/vendor/rails/actionwebservice/CHANGELOG +++ b/tracks/vendor/rails/actionwebservice/CHANGELOG @@ -1,3 +1,18 @@ +*1.1.5* (August 8th, 2006) + +* Rely on Action Pack 1.12.4 and Active Record 1.14.4 + + +*1.1.4* (June 29th, 2006) + +* Rely on Action Pack 1.12.3 + + +*1.1.3* (June 27th, 2006) + +* Rely on Action Pack 1.12.2 and Active Record 1.14.3 + + *1.1.2* (April 9th, 2005) * Rely on Active Record 1.14.2 diff --git a/tracks/vendor/rails/actionwebservice/Rakefile b/tracks/vendor/rails/actionwebservice/Rakefile index 953e4730..8207f2e1 100644 --- a/tracks/vendor/rails/actionwebservice/Rakefile +++ b/tracks/vendor/rails/actionwebservice/Rakefile @@ -71,8 +71,8 @@ spec = Gem::Specification.new do |s| s.rubyforge_project = "aws" s.homepage = "http://www.rubyonrails.org" - s.add_dependency('actionpack', '= 1.12.1' + PKG_BUILD) - s.add_dependency('activerecord', '= 1.14.2' + PKG_BUILD) + s.add_dependency('actionpack', '= 1.12.4' + PKG_BUILD) + s.add_dependency('activerecord', '= 1.14.4' + PKG_BUILD) s.has_rdoc = true s.requirements << 'none' diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/version.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/version.rb index aa2a4586..4f82a6e1 100644 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/version.rb +++ b/tracks/vendor/rails/actionwebservice/lib/action_web_service/version.rb @@ -2,7 +2,7 @@ module ActionWebService module VERSION #:nodoc: MAJOR = 1 MINOR = 1 - TINY = 2 + TINY = 5 STRING = [MAJOR, MINOR, TINY].join('.') end diff --git a/tracks/vendor/rails/activerecord/CHANGELOG b/tracks/vendor/rails/activerecord/CHANGELOG index 07aa0921..34db2bc1 100644 --- a/tracks/vendor/rails/activerecord/CHANGELOG +++ b/tracks/vendor/rails/activerecord/CHANGELOG @@ -1,9 +1,31 @@ -*1.14.2* (April 9th, 2005) +*1.14.4* (August 8th, 2006) + +* Add warning about the proper way to validate the presence of a foreign key. #4147 [Francois Beausoleil ] + +* Fix syntax error in documentation. #4679 [mislav@nippur.irb.hr] + +* Update inconsistent migrations documentation. #4683 [machomagna@gmail.com] + + +*1.14.3* (June 27th, 2006) + +* Fix announcement of very long migration names. #5722 [blake@near-time.com] + +* Update callbacks documentation. #3970 [Robby Russell ] + +* Properly quote index names in migrations (closes #4764) [John Long] + +* Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick] + +* Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick] + + +*1.14.2* (April 9th, 2006) * Fixed calculations for the Oracle Adapter (closes #4626) [Michael Schoen] -*1.14.1* (April 6th, 2005) +*1.14.1* (April 6th, 2006) * Fix type_name_with_module to handle type names that begin with '::'. Closes #4614. [Nicholas Seckar] @@ -58,7 +80,7 @@ * Fixed broken OCIAdapter #4457 [schoenm@earthlink.net] -*1.14.0* (March 27th, 2005) +*1.14.0* (March 27th, 2006) * Replace 'rescue Object' with a finer grained rescue. Closes #4431. [Nicholas Seckar] @@ -478,6 +500,7 @@ * Fixed :through relations when using STI inherited classes would use the inherited class's name as foreign key on the join model [Tobias Luetke] + *1.13.2* (December 13th, 2005) * Become part of Rails 1.0 diff --git a/tracks/vendor/rails/activerecord/Rakefile b/tracks/vendor/rails/activerecord/Rakefile index f678f866..f02c3b5c 100644 --- a/tracks/vendor/rails/activerecord/Rakefile +++ b/tracks/vendor/rails/activerecord/Rakefile @@ -173,8 +173,8 @@ desc "Publish the release files to RubyForge." task :release => [ :package ] do `rubyforge login` - for ext in %w( gem ) - release_command = "rubyforge add_release activerecord activerecord 'REL #{PKG_VERSION}' pkg/activerecord-#{PKG_VERSION}.#{ext}" + for ext in %w( gem tgz zip ) + release_command = "rubyforge add_release #{PKG_NAME} #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" puts release_command system(release_command) end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations.rb index 36998363..ea497d5c 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/associations.rb @@ -1163,18 +1163,19 @@ module ActiveRecord end def select_limited_ids_list(options, join_dependency) - connection.select_values( + connection.select_all( construct_finder_sql_for_association_limiting(options, join_dependency), "#{name} Load IDs For Limited Eager Loading" - ).collect { |id| connection.quote(id) }.join(", ") + ).collect { |row| connection.quote(row[primary_key]) }.join(", ") end def construct_finder_sql_for_association_limiting(options, join_dependency) scope = scope(:find) - #sql = "SELECT DISTINCT #{table_name}.#{primary_key} FROM #{table_name} " sql = "SELECT " sql << "DISTINCT #{table_name}." if include_eager_conditions?(options) || include_eager_order?(options) - sql << "#{primary_key} FROM #{table_name} " + sql << primary_key + sql << ", #{options[:order].split(',').collect { |s| s.split.first } * ', '}" if options[:order] && (include_eager_conditions?(options) || include_eager_order?(options)) + sql << " FROM #{table_name} " if include_eager_conditions?(options) || include_eager_order?(options) sql << join_dependency.join_associations.collect{|join| join.association_join }.join @@ -1186,16 +1187,24 @@ module ActiveRecord add_limit!(sql, options, scope) return sanitize_sql(sql) end - + + # Checks if the conditions reference a table other than the current model table def include_eager_conditions?(options) - conditions = scope(:find, :conditions) || options[:conditions] - return false unless conditions - conditions = conditions.first if conditions.is_a?(Array) - conditions.scan(/(\w+)\.\w+/).flatten.any? do |condition_table_name| + # look in both sets of conditions + conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond| + case cond + when nil then all + when Array then all << cond.first + else all << cond + end + end + return false unless conditions.any? + conditions.join(' ').scan(/(\w+)\.\w+/).flatten.any? do |condition_table_name| condition_table_name != table_name end end + # Checks if the query order references a table other than the current model's table. def include_eager_order?(options) order = options[:order] return false unless order diff --git a/tracks/vendor/rails/activerecord/lib/active_record/base.rb b/tracks/vendor/rails/activerecord/lib/active_record/base.rb index 106432ed..6c3d1022 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/base.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/base.rb @@ -175,7 +175,7 @@ module ActiveRecord #:nodoc: # serialize :preferences # end # - # user = User.create(:preferences) => { "background" => "black", "display" => large }) + # user = User.create(:preferences => { "background" => "black", "display" => large }) # User.find(user.id).preferences # => { "background" => "black", "display" => large } # # You can also specify a class option as the second parameter that'll raise an exception if a serialized object is retrieved as a diff --git a/tracks/vendor/rails/activerecord/lib/active_record/calculations.rb b/tracks/vendor/rails/activerecord/lib/active_record/calculations.rb index d586bec8..863aedbf 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/calculations.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/calculations.rb @@ -42,26 +42,29 @@ module ActiveRecord # # Note: Person.count(:all) will not work because it will use :all as the condition. Use Person.count instead. def count(*args) - options = {} - - #For backwards compatibility, we need to handle both count(conditions=nil, joins=nil) or count(options={}). - if args.size >= 0 and args.size <= 2 + options = {} + column_name = :all + # For backwards compatibility, we need to handle both count(conditions=nil, joins=nil) or count(options={}) or count(column_name=:all, options={}). + if args.size >= 0 && args.size <= 2 if args.first.is_a?(Hash) - options = args.first - #should we verify the options hash??? + options = args.first elsif args[1].is_a?(Hash) + options = args[1] column_name = args.first - options = args[1] else - # Handle legacy paramter options: def count(conditions=nil, joins=nil) + # Handle legacy paramter options: def count(conditions=nil, joins=nil) options.merge!(:conditions => args[0]) if args.length > 0 - options.merge!(:joins => args[1]) if args.length > 1 + options.merge!(:joins => args[1]) if args.length > 1 end else raise(ArgumentError, "Unexpected parameters passed to count(*args): expected either count(conditions=nil, joins=nil) or count(options={})") end - (scope(:find, :include) || options[:include]) ? count_with_associations(options) : calculate(:count, :all, options) + if options[:include] || scope(:find, :include) + count_with_associations(options) + else + calculate(:count, column_name, options) + end end # Calculates average value on a given column. The value is returned as a float. See #calculate for examples with options. diff --git a/tracks/vendor/rails/activerecord/lib/active_record/callbacks.rb b/tracks/vendor/rails/activerecord/lib/active_record/callbacks.rb index 2ffb52ad..454518d2 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/callbacks.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/callbacks.rb @@ -243,6 +243,10 @@ module ActiveRecord def before_save() end # Is called _after_ Base.save (regardless of whether it's a create or update save). + # + # class Contact < ActiveRecord::Base + # after_save { logger.info( 'New contact saved!' ) } + # end def after_save() end def create_or_update_with_callbacks #:nodoc: return false if callback(:before_save) == false @@ -312,9 +316,16 @@ module ActiveRecord end # Is called _before_ Base.destroy. + # + # Note: If you need to _destroy_ or _nullify_ associated records first, + # use the _:dependent_ option on your associations. def before_destroy() end # Is called _after_ Base.destroy (and all the attributes have been frozen). + # + # class Contact < ActiveRecord::Base + # after_destroy { |record| logger.info( "Contact #{record.id} was destroyed." ) } + # end def after_destroy() end def destroy_with_callbacks #:nodoc: return false if callback(:before_destroy) == false diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index c0052822..b57f2c86 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -119,7 +119,7 @@ module ActiveRecord # Adds a new column to the named table. # See TableDefinition#column for details of the options you can use. def add_column(table_name, column_name, type, options = {}) - add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}" + add_column_sql = "ALTER TABLE #{table_name} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit])}" add_column_options!(add_column_sql, options) execute(add_column_sql) end @@ -128,7 +128,7 @@ module ActiveRecord # ===== Examples # remove_column(:suppliers, :qualification) def remove_column(table_name, column_name) - execute "ALTER TABLE #{table_name} DROP #{column_name}" + execute "ALTER TABLE #{table_name} DROP #{quote_column_name(column_name)}" end # Changes the column's definition according to the new options. @@ -184,7 +184,8 @@ module ActiveRecord # generates # CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id) def add_index(table_name, column_name, options = {}) - index_name = "#{table_name}_#{Array(column_name).first}_index" + column_names = Array(column_name) + index_name = index_name(table_name, :column => column_names.first) if Hash === options # legacy support, since this param was a string index_type = options[:unique] ? "UNIQUE" : "" @@ -192,8 +193,8 @@ module ActiveRecord else index_type = options end - - execute "CREATE #{index_type} INDEX #{index_name} ON #{table_name} (#{Array(column_name).join(", ")})" + quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ") + execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names})" end # Remove the given index from the table. @@ -209,7 +210,7 @@ module ActiveRecord # add_index :accounts, [:username, :password] # remove_index :accounts, :username def remove_index(table_name, options = {}) - execute "DROP INDEX #{index_name(table_name, options)} ON #{table_name}" + execute "DROP INDEX #{quote_column_name(index_name(table_name, options))} ON #{table_name}" end def index_name(table_name, options) #:nodoc: diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 22344761..7a697c23 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -18,7 +18,6 @@ module ActiveRecord end end - config = config.symbolize_keys host = config[:host] port = config[:port] diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index ba26b05a..c3b076fe 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -337,8 +337,7 @@ module ActiveRecord def remove_index(table_name, options) #:nodoc: execute "DROP INDEX #{index_name(table_name, options)}" - end - + end private BYTEA_COLUMN_TYPE_OID = 17 diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 40933d74..ba219b97 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -213,13 +213,7 @@ module ActiveRecord end def remove_index(table_name, options={}) #:nodoc: - if Hash === options - index_name = options[:name] - else - index_name = "#{table_name}_#{options}_index" - end - - execute "DROP INDEX #{index_name}" + execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}" end def rename_table(name, new_name) diff --git a/tracks/vendor/rails/activerecord/lib/active_record/migration.rb b/tracks/vendor/rails/activerecord/lib/active_record/migration.rb index d3581e2c..a1934d40 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/migration.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/migration.rb @@ -70,8 +70,8 @@ module ActiveRecord # * change_column(table_name, column_name, type, options): Changes the column to a different type using the same # parameters as add_column. # * remove_column(table_name, column_name): Removes the column named +column_name+ from the table called +table_name+. - # * add_index(table_name, column_name, index_type): Add a new index with the name of the column on the column. Specify an optional index_type (e.g. UNIQUE). - # * remove_index(table_name, column_name): Remove the index called the same as the column. + # * add_index(table_name, column_names, index_type, index_name): Add a new index with the name of the column, or +index_name+ (if specified) on the column(s). Specify an optional +index_type+ (e.g. UNIQUE). + # * remove_index(table_name, index_name): Remove the index specified by +index_name+. # # == Irreversible transformations # @@ -243,7 +243,8 @@ module ActiveRecord def announce(message) text = "#{name}: #{message}" - write "== %s %s" % [ text, "=" * (75 - text.length) ] + length = [0, 75 - text.length].max + write "== %s %s" % [text, "=" * length] end def say(message, subitem=false) diff --git a/tracks/vendor/rails/activerecord/lib/active_record/validations.rb b/tracks/vendor/rails/activerecord/lib/active_record/validations.rb index fec2f59a..f34871c3 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/validations.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/validations.rb @@ -381,6 +381,18 @@ module ActiveRecord # * if - Specifies a method, proc or string to call to determine if the validation should # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The # method, proc or string should return or evaluate to a true or false value. + # + # === Warning + # Validate the presence of the foreign key, not the instance variable itself. + # Do this: + # validate_presence_of :invoice_id + # + # Not this: + # validate_presence_of :invoice + # + # If you validate the presence of the associated object, you will get + # failures on saves when both the parent object and the child object are + # new. def validates_presence_of(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:blank], :on => :save } configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) diff --git a/tracks/vendor/rails/activerecord/lib/active_record/version.rb b/tracks/vendor/rails/activerecord/lib/active_record/version.rb index 3158040d..4568a1b4 100644 --- a/tracks/vendor/rails/activerecord/lib/active_record/version.rb +++ b/tracks/vendor/rails/activerecord/lib/active_record/version.rb @@ -2,7 +2,7 @@ module ActiveRecord module VERSION #:nodoc: MAJOR = 1 MINOR = 14 - TINY = 2 + TINY = 4 STRING = [MAJOR, MINOR, TINY].join('.') end diff --git a/tracks/vendor/rails/activerecord/test/associations_go_eager_test.rb b/tracks/vendor/rails/activerecord/test/associations_go_eager_test.rb index 324e8eb2..d2ae4e0d 100644 --- a/tracks/vendor/rails/activerecord/test/associations_go_eager_test.rb +++ b/tracks/vendor/rails/activerecord/test/associations_go_eager_test.rb @@ -179,6 +179,42 @@ class EagerAssociationTest < Test::Unit::TestCase assert_equal count, posts.size end + def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers + posts = nil + Post.with_scope(:find => { + :include => :comments, + :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'" + }) do + posts = authors(:david).posts.find(:all, :limit => 2) + assert_equal 2, posts.size + end + + Post.with_scope(:find => { + :include => [ :comments, :author ], + :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')" + }) do + count = Post.count(:limit => 2) + assert_equal count, posts.size + end + end + + def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers + Post.with_scope(:find => { :conditions => "1=1" }) do + posts = authors(:david).posts.find(:all, + :include => :comments, + :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'", + :limit => 2 + ) + assert_equal 2, posts.size + + count = Post.count( + :include => [ :comments, :author ], + :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')", + :limit => 2 + ) + assert_equal count, posts.size + end + end def test_eager_association_loading_with_habtm posts = Post.find(:all, :include => :categories, :order => "posts.id") assert_equal 2, posts[0].categories.size diff --git a/tracks/vendor/rails/activerecord/test/base_test.rb b/tracks/vendor/rails/activerecord/test/base_test.rb index 63bc3ea6..f5ad7abc 100644 --- a/tracks/vendor/rails/activerecord/test/base_test.rb +++ b/tracks/vendor/rails/activerecord/test/base_test.rb @@ -922,6 +922,16 @@ class BasicsTest < Test::Unit::TestCase assert_equal("", inverted["quux"]) end + def test_sql_injection_via_find + assert_raises(ActiveRecord::RecordNotFound) do + Topic.find("123456 OR id > 0") + end + + assert_raises(ActiveRecord::RecordNotFound) do + Topic.find(";;; this should raise an RecordNotFound error") + end + end + def test_column_name_properly_quoted col_record = ColumnName.new col_record.references = 40 diff --git a/tracks/vendor/rails/activerecord/test/migration_test.rb b/tracks/vendor/rails/activerecord/test/migration_test.rb index 7c19b074..c6a1d924 100644 --- a/tracks/vendor/rails/activerecord/test/migration_test.rb +++ b/tracks/vendor/rails/activerecord/test/migration_test.rb @@ -34,6 +34,7 @@ if ActiveRecord::Base.connection.supports_migrations? Reminder.reset_column_information Person.connection.remove_column("people", "last_name") rescue nil + Person.connection.remove_column("people", "key") rescue nil Person.connection.remove_column("people", "bio") rescue nil Person.connection.remove_column("people", "age") rescue nil Person.connection.remove_column("people", "height") rescue nil @@ -47,12 +48,17 @@ if ActiveRecord::Base.connection.supports_migrations? def test_add_index Person.connection.add_column "people", "last_name", :string Person.connection.add_column "people", "administrator", :boolean + Person.connection.add_column "people", "key", :string assert_nothing_raised { Person.connection.add_index("people", "last_name") } assert_nothing_raised { Person.connection.remove_index("people", "last_name") } assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) } assert_nothing_raised { Person.connection.remove_index("people", "last_name") } + + # quoting + assert_nothing_raised { Person.connection.add_index("people", ["key"], :name => "key", :unique => true) } + assert_nothing_raised { Person.connection.remove_index("people", :name => "key") } # Sybase adapter does not support indexes on :boolean columns unless current_adapter?(:SybaseAdapter) diff --git a/tracks/vendor/rails/railties/CHANGELOG b/tracks/vendor/rails/railties/CHANGELOG index 1a0b0c58..238b4a30 100644 --- a/tracks/vendor/rails/railties/CHANGELOG +++ b/tracks/vendor/rails/railties/CHANGELOG @@ -1,11 +1,32 @@ -*1.1.2* (April 9th, 2005) +*1.1.5* (August 8th, 2006) + +* Mention in docs that config.frameworks doesn't work when getting Rails via Gems. #4857 [Alisdair McDiarmid] + +* Change the scaffolding layout to use yield rather than @content_for_layout. [Marcel Molina Jr.] + +* Includes critical security patch + + +*1.1.4* (June 29th, 2006) + +* Remove use of opts.on { |options[:name] } style hash assignment. References #4440. [headius@headius.com] + +* Updated to Action Pack 1.12.3, ActionWebService 1.1.4, ActionMailer 1.2.3 + + +*1.1.3* (June 27th, 2006) + +* Updated to Active Record 1.14.3, Action Pack 1.12.2, ActionWebService 1.1.3, ActionMailer 1.2.2 + + +*1.1.2* (April 9th, 2006) * Added rake rails:update:configs to update config/boot.rb from the latest (also included in rake rails:update) [DHH] * Fixed that boot.rb would set RAILS_GEM_VERSION twice, not respect an uncommented RAILS_GEM_VERSION line, and not use require_gem [DHH] -*1.1.1* (April 6th, 2005) +*1.1.1* (April 6th, 2006) * Enhances plugin#discover allowing it to discover svn:// like URIs (closes #4565) [ruben.nine@gmail.com] @@ -44,7 +65,7 @@ * Avoid passing escapeHTML non-string in Rails' info controller [Nicholas Seckar] -*1.1.0* (March 27th, 2005) +*1.1.0* (March 27th, 2006) * Allow db:fixtures:load to load a subset of the applications fixtures. [Chad Fowler] @@ -185,6 +206,7 @@ * Honor ActiveRecord::Base.pluralize_table_names when creating and destroying session store table. #3204. [rails@bencurtis.com, Marcel Molina Jr.] + *1.0.0* (December 13th, 2005) * Update instructions on how to find and install generators. #3172. [Chad Fowler] diff --git a/tracks/vendor/rails/railties/README b/tracks/vendor/rails/railties/README index b8e35692..7d8965e6 100644 --- a/tracks/vendor/rails/railties/README +++ b/tracks/vendor/rails/railties/README @@ -124,6 +124,9 @@ application is running. You can inspect domain models, change values, and save t database. Starting the script without arguments will launch it in the development environment. Passing an argument will specify a different environment, like script/console production. +To reload your controllers and models after launching the console run reload! + + == Description of contents diff --git a/tracks/vendor/rails/railties/Rakefile b/tracks/vendor/rails/railties/Rakefile index 40f5f4e4..aea1e449 100644 --- a/tracks/vendor/rails/railties/Rakefile +++ b/tracks/vendor/rails/railties/Rakefile @@ -279,10 +279,10 @@ spec = Gem::Specification.new do |s| s.add_dependency('rake', '>= 0.7.1') s.add_dependency('activesupport', '= 1.3.1' + PKG_BUILD) - s.add_dependency('activerecord', '= 1.14.2' + PKG_BUILD) - s.add_dependency('actionpack', '= 1.12.1' + PKG_BUILD) - s.add_dependency('actionmailer', '= 1.2.1' + PKG_BUILD) - s.add_dependency('actionwebservice', '= 1.1.2' + PKG_BUILD) + s.add_dependency('activerecord', '= 1.14.4' + PKG_BUILD) + s.add_dependency('actionpack', '= 1.12.4' + PKG_BUILD) + s.add_dependency('actionmailer', '= 1.2.4' + PKG_BUILD) + s.add_dependency('actionwebservice', '= 1.1.5' + PKG_BUILD) s.rdoc_options << '--exclude' << '.' s.has_rdoc = false diff --git a/tracks/vendor/rails/railties/environments/environment.rb b/tracks/vendor/rails/railties/environments/environment.rb index 839da1c5..0620d3ed 100644 --- a/tracks/vendor/rails/railties/environments/environment.rb +++ b/tracks/vendor/rails/railties/environments/environment.rb @@ -13,7 +13,7 @@ require File.join(File.dirname(__FILE__), 'boot') Rails::Initializer.run do |config| # Settings in config/environments/* take precedence those specified here - # Skip frameworks you're not going to use + # Skip frameworks you're not going to use (only works if using vendor/rails) # config.frameworks -= [ :action_web_service, :action_mailer ] # Add additional load paths for your own custom dirs diff --git a/tracks/vendor/rails/railties/lib/commands/console.rb b/tracks/vendor/rails/railties/lib/commands/console.rb index ed0cc10d..8b35a8d2 100644 --- a/tracks/vendor/rails/railties/lib/commands/console.rb +++ b/tracks/vendor/rails/railties/lib/commands/console.rb @@ -4,8 +4,8 @@ require 'optparse' options = { :sandbox => false, :irb => irb } OptionParser.new do |opt| opt.banner = "Usage: console [environment] [options]" - opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |options[:sandbox]| } - opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |options[:irb]| } + opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |v| options[:sandbox] = v } + opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |v| options[:irb] = v } opt.parse!(ARGV) end diff --git a/tracks/vendor/rails/railties/lib/commands/process/reaper.rb b/tracks/vendor/rails/railties/lib/commands/process/reaper.rb index 73b6b97f..d0126c72 100644 --- a/tracks/vendor/rails/railties/lib/commands/process/reaper.rb +++ b/tracks/vendor/rails/railties/lib/commands/process/reaper.rb @@ -117,8 +117,8 @@ ARGV.options do |opts| opts.on(" Options:") - opts.on("-a", "--action=name", "reload|graceful|kill (default: #{OPTIONS[:action]})", String) { |OPTIONS[:action]| } - opts.on("-d", "--dispatcher=path", "default: #{OPTIONS[:dispatcher]}", String) { |OPTIONS[:dispatcher]| } + opts.on("-a", "--action=name", "reload|graceful|kill (default: #{OPTIONS[:action]})", String) { |v| OPTIONS[:action] = v } + opts.on("-d", "--dispatcher=path", "default: #{OPTIONS[:dispatcher]}", String) { |v| OPTIONS[:dispatcher] = v } opts.separator "" diff --git a/tracks/vendor/rails/railties/lib/commands/process/spawner.rb b/tracks/vendor/rails/railties/lib/commands/process/spawner.rb index 84364589..8c76a1c7 100644 --- a/tracks/vendor/rails/railties/lib/commands/process/spawner.rb +++ b/tracks/vendor/rails/railties/lib/commands/process/spawner.rb @@ -65,11 +65,11 @@ ARGV.options do |opts| opts.on(" Options:") - opts.on("-p", "--port=number", Integer, "Starting port number (default: #{OPTIONS[:port]})") { |OPTIONS[:port]| } - opts.on("-i", "--instances=number", Integer, "Number of instances (default: #{OPTIONS[:instances]})") { |OPTIONS[:instances]| } - opts.on("-r", "--repeat=seconds", Integer, "Repeat spawn attempts every n seconds (default: off)") { |OPTIONS[:repeat]| } - opts.on("-e", "--environment=name", String, "test|development|production (default: #{OPTIONS[:environment]})") { |OPTIONS[:environment]| } - opts.on("-s", "--spawner=path", String, "default: #{OPTIONS[:spawner]}") { |OPTIONS[:spawner]| } + opts.on("-p", "--port=number", Integer, "Starting port number (default: #{OPTIONS[:port]})") { |v| OPTIONS[:port] = v } + opts.on("-i", "--instances=number", Integer, "Number of instances (default: #{OPTIONS[:instances]})") { |v| OPTIONS[:instances] = v } + opts.on("-r", "--repeat=seconds", Integer, "Repeat spawn attempts every n seconds (default: off)") { |v| OPTIONS[:repeat] = v } + opts.on("-e", "--environment=name", String, "test|development|production (default: #{OPTIONS[:environment]})") { |v| OPTIONS[:environment] = v } + opts.on("-s", "--spawner=path", String, "default: #{OPTIONS[:spawner]}") { |v| OPTIONS[:spawner] = v } opts.on("-d", "--dispatcher=path", String, "default: #{OPTIONS[:dispatcher]}") { |dispatcher| OPTIONS[:dispatcher] = File.expand_path(dispatcher) } opts.separator "" diff --git a/tracks/vendor/rails/railties/lib/commands/process/spinner.rb b/tracks/vendor/rails/railties/lib/commands/process/spinner.rb index af073c74..c0b2f09a 100644 --- a/tracks/vendor/rails/railties/lib/commands/process/spinner.rb +++ b/tracks/vendor/rails/railties/lib/commands/process/spinner.rb @@ -36,9 +36,9 @@ ARGV.options do |opts| opts.on(" Options:") - opts.on("-c", "--command=path", String) { |OPTIONS[:command]| } - opts.on("-i", "--interval=seconds", Float) { |OPTIONS[:interval]| } - opts.on("-d", "--daemon") { |OPTIONS[:daemon]| } + opts.on("-c", "--command=path", String) { |v| OPTIONS[:command] = v } + opts.on("-i", "--interval=seconds", Float) { |v| OPTIONS[:interval] = v } + opts.on("-d", "--daemon") { |v| OPTIONS[:daemon] = v } opts.separator "" diff --git a/tracks/vendor/rails/railties/lib/commands/runner.rb b/tracks/vendor/rails/railties/lib/commands/runner.rb index f4d70f15..47186d52 100644 --- a/tracks/vendor/rails/railties/lib/commands/runner.rb +++ b/tracks/vendor/rails/railties/lib/commands/runner.rb @@ -10,7 +10,7 @@ ARGV.options do |opts| opts.on("-e", "--environment=name", String, "Specifies the environment for the runner to operate under (test/development/production).", - "Default: development") { |options[:environment]| } + "Default: development") { |v| options[:environment] = v } opts.separator "" diff --git a/tracks/vendor/rails/railties/lib/commands/servers/webrick.rb b/tracks/vendor/rails/railties/lib/commands/servers/webrick.rb index db8e8b3d..3fddcc54 100644 --- a/tracks/vendor/rails/railties/lib/commands/servers/webrick.rb +++ b/tracks/vendor/rails/railties/lib/commands/servers/webrick.rb @@ -19,13 +19,13 @@ ARGV.options do |opts| opts.on("-p", "--port=port", Integer, "Runs Rails on the specified port.", - "Default: 3000") { |OPTIONS[:port]| } + "Default: 3000") { |v| OPTIONS[:port] = v } opts.on("-b", "--binding=ip", String, "Binds Rails to the specified ip.", - "Default: 0.0.0.0") { |OPTIONS[:ip]| } + "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v } opts.on("-e", "--environment=name", String, "Specifies the environment to run this server under (test/development/production).", - "Default: development") { |OPTIONS[:environment]| } + "Default: development") { |v| OPTIONS[:environment] = v } opts.on("-m", "--mime-types=filename", String, "Specifies an Apache style mime.types configuration file to be used for mime types", "Default: none") { |mime_types_file| OPTIONS[:mime_types] = WEBrick::HTTPUtils::load_mime_types(mime_types_file) } @@ -36,7 +36,7 @@ ARGV.options do |opts| opts.on("-c", "--charset=charset", String, "Set default charset for output.", - "Default: UTF-8") { |OPTIONS[:charset]| } + "Default: UTF-8") { |v| OPTIONS[:charset] = v } opts.separator "" diff --git a/tracks/vendor/rails/railties/lib/rails/version.rb b/tracks/vendor/rails/railties/lib/rails/version.rb index bc87eeac..53ae16a3 100644 --- a/tracks/vendor/rails/railties/lib/rails/version.rb +++ b/tracks/vendor/rails/railties/lib/rails/version.rb @@ -2,7 +2,7 @@ module Rails module VERSION #:nodoc: MAJOR = 1 MINOR = 1 - TINY = 2 + TINY = 5 STRING = [MAJOR, MINOR, TINY].join('.') end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb index f1f800cf..d59c1d05 100644 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb +++ b/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb @@ -96,15 +96,15 @@ class AppGenerator < Rails::Generator::Base opt.separator 'Options:' opt.on("-r", "--ruby=path", String, "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).", - "Default: #{DEFAULT_SHEBANG}") { |options[:shebang]| } + "Default: #{DEFAULT_SHEBANG}") { |v| options[:shebang] = v } opt.on("-d", "--database=name", String, "Preconfigure for selected database (options: mysql/oracle/postgresql/sqlite2/sqlite3).", - "Default: mysql") { |options[:db]| } + "Default: mysql") { |v| options[:db] = v } opt.on("-f", "--freeze", "Freeze Rails in vendor/rails from the gems generating the skeleton", - "Default: false") { |options[:freeze]| } + "Default: false") { |v| options[:freeze] = v } end def mysql_socket_location diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb index 0940b57f..e2424826 100644 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb +++ b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb @@ -29,6 +29,6 @@ class ModelGenerator < Rails::Generator::NamedBase opt.separator '' opt.separator 'Options:' opt.on("--skip-migration", - "Don't generate a migration file for this model") { |options[:skip_migration]| } + "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } end end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml index 3e969b9a..b5ba9a4e 100644 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +++ b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml @@ -7,7 +7,7 @@

<%%= flash[:notice] %>

-<%%= @content_for_layout %> +<%%= yield %> diff --git a/tracks/vendor/rails/railties/lib/rails_generator/options.rb b/tracks/vendor/rails/railties/lib/rails_generator/options.rb index fe80f834..5cafa557 100644 --- a/tracks/vendor/rails/railties/lib/rails_generator/options.rb +++ b/tracks/vendor/rails/railties/lib/rails_generator/options.rb @@ -121,12 +121,12 @@ module Rails opt.separator '' opt.separator 'General Options:' - opt.on('-p', '--pretend', 'Run but do not make any changes.') { |options[:pretend]| } + opt.on('-p', '--pretend', 'Run but do not make any changes.') { |v| options[:pretend] = v } opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force } opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip } - opt.on('-q', '--quiet', 'Suppress normal output.') { |options[:quiet]| } - opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |options[:backtrace]| } - opt.on('-h', '--help', 'Show this help message.') { |options[:help]| } + opt.on('-q', '--quiet', 'Suppress normal output.') { |v| options[:quiet] = v } + opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |v| options[:backtrace] = v } + opt.on('-h', '--help', 'Show this help message.') { |v| options[:help] = v } opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do options[:svn] = `svn status`.inject({}) do |opt, e| opt[e.chomp[7..-1]] = true diff --git a/tracks/vendor/rails/railties/lib/rails_generator/scripts.rb b/tracks/vendor/rails/railties/lib/rails_generator/scripts.rb index 2bf3b1b0..14156e9c 100644 --- a/tracks/vendor/rails/railties/lib/rails_generator/scripts.rb +++ b/tracks/vendor/rails/railties/lib/rails_generator/scripts.rb @@ -38,7 +38,7 @@ module Rails protected # Override with your own script usage banner. def banner - "Usage: #{$0} [options] generator [args]" + "Usage: #{$0} generator [options] [args]" end def usage_message