Blog post here: http://developer.uservoice.com/entries/how-to-upgrade-a-rails-2.3.14-app-to-ruby-1.9.3/
-
-
Save nbrew/2244978 to your computer and use it in GitHub Desktop.
Rails 2.3.14 Ruby 1.9.3 - Monkey Patches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# At the top of environment.rb, set your default encodings: | |
Encoding.default_external = Encoding.default_internal = Encoding::UTF_8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This little guy is needed unless you want to define a helper for every single one of your controllers | |
MissingSourceFile::REGEXPS << [/^cannot load such file -- (.+)$/i, 1] | |
# TZInfo needs to be patched. In particular, you'll need to re-implement the datetime_new! method: | |
require 'tzinfo' | |
module TZInfo | |
# Methods to support different versions of Ruby. | |
module RubyCoreSupport #:nodoc: | |
# Ruby 1.8.6 introduced new! and deprecated new0. | |
# Ruby 1.9.0 removed new0. | |
# Ruby trunk revision 31668 removed the new! method. | |
# Still support new0 for better performance on older versions of Ruby (new0 indicates | |
# that the rational has already been reduced to its lowest terms). | |
# Fallback to jd with conversion from ajd if new! and new0 are unavailable. | |
if DateTime.respond_to? :new! | |
def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY) | |
DateTime.new!(ajd, of, sg) | |
end | |
elsif DateTime.respond_to? :new0 | |
def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY) | |
DateTime.new0(ajd, of, sg) | |
end | |
else | |
HALF_DAYS_IN_DAY = rational_new!(1, 2) | |
def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY) | |
# Convert from an Astronomical Julian Day number to a civil Julian Day number. | |
jd = ajd + of + HALF_DAYS_IN_DAY | |
# Ruby trunk revision 31862 changed the behaviour of DateTime.jd so that it will no | |
# longer accept a fractional civil Julian Day number if further arguments are specified. | |
# Calculate the hours, minutes and seconds to pass to jd. | |
jd_i = jd.to_i | |
jd_i -= 1 if jd < 0 | |
hours = (jd - jd_i) * 24 | |
hours_i = hours.to_i | |
minutes = (hours - hours_i) * 60 | |
minutes_i = minutes.to_i | |
seconds = (minutes - minutes_i) * 60 | |
DateTime.jd(jd_i, hours_i, minutes_i, seconds, of, sg) | |
end | |
end | |
end | |
end | |
# Finally, we have this innocuous looking patch. Without it, queries like this: current_account.tickets.recent.count | |
# would instantiate AR objects all (!!) tickets in the account, not merely return a count of the recent ones. | |
# See https://rails.lighthouseapp.com/projects/8994/tickets/5410-multiple-database-queries-when-chaining-named-scopes-with-rails-238-and-ruby-192 | |
# (The patch in that lighthouse bug was not, in fact, merged in). | |
module ActiveRecord | |
module Associations | |
class AssociationProxy | |
def respond_to_missing?(meth, incl_priv) | |
false | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Make sure the logger supports encodings properly. | |
module ActiveSupport | |
class BufferedLogger | |
def add(severity, message = nil, progname = nil, &block) | |
return if @level > severity | |
message = (message || (block && block.call) || progname).to_s | |
# If a newline is necessary then create a new message ending with a newline. | |
# Ensures that the original message is not mutated. | |
message = "#{message}\n" unless message[-1] == ?\n | |
buffer << message.force_encoding(Encoding.default_external) | |
auto_flush | |
message | |
end | |
end | |
end | |
# This makes it so all parameters get converted to UTF-8 before they hit your app. If someone sends invalid UTF-8 to your server, raise an exception. | |
# At UserVoice, we rescue this exception and show a custom error page. | |
class ActionController::InvalidByteSequenceErrorFromParams < Encoding::InvalidByteSequenceError; end | |
class ActionController::Base | |
def force_utf8_params | |
traverse = lambda do |object, block| | |
if object.kind_of?(Hash) | |
object.each_value { |o| traverse.call(o, block) } | |
elsif object.kind_of?(Array) | |
object.each { |o| traverse.call(o, block) } | |
else | |
block.call(object) | |
end | |
object | |
end | |
force_encoding = lambda do |o| | |
if o.respond_to?(:force_encoding) | |
o.force_encoding(Encoding::UTF_8) | |
raise ActionController::InvalidByteSequenceErrorFromParams unless o.valid_encoding? | |
end | |
if o.respond_to?(:original_filename) | |
o.original_filename.force_encoding(Encoding::UTF_8) | |
raise ActionController::InvalidByteSequenceErrorFromParams unless o.original_filename.valid_encoding? | |
end | |
end | |
traverse.call(params, force_encoding) | |
path_str = request.path.to_s | |
if path_str.respond_to?(:force_encoding) | |
path_str.force_encoding(Encoding::UTF_8) | |
raise ActionController::InvalidByteSequenceErrorFromParams unless path_str.valid_encoding? | |
end | |
end | |
before_filter :force_utf8_params | |
end | |
# Serialized columns in AR don't support UTF-8 well, so set the encoding on those as well. | |
class ActiveRecord::Base | |
def unserialize_attribute_with_utf8(attr_name) | |
traverse = lambda do |object, block| | |
if object.kind_of?(Hash) | |
object.each_value { |o| traverse.call(o, block) } | |
elsif object.kind_of?(Array) | |
object.each { |o| traverse.call(o, block) } | |
else | |
block.call(object) | |
end | |
object | |
end | |
force_encoding = lambda do |o| | |
o.force_encoding(Encoding::UTF_8) if o.respond_to?(:force_encoding) | |
end | |
value = unserialize_attribute_without_utf8(attr_name) | |
traverse.call(value, force_encoding) | |
end | |
alias_method_chain :unserialize_attribute, :utf8 | |
end | |
# Make sure the flash sets the encoding to UTF-8 as well. | |
module ActionController | |
module Flash | |
class FlashHash | |
def [](k) | |
v = super | |
v.is_a?(String) ? v.force_encoding("UTF-8") : v | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment