From 7531aa76417a5db337287c31c1b97ad53615c8e6 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Thu, 15 Sep 2011 10:41:55 +0400 Subject: update guides, use html safe translations in i18n --- .../guides/assets/images/i18n/demo_html_safe.png | Bin 0 -> 11946 bytes railties/guides/source/i18n.textile | 22 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 railties/guides/assets/images/i18n/demo_html_safe.png diff --git a/railties/guides/assets/images/i18n/demo_html_safe.png b/railties/guides/assets/images/i18n/demo_html_safe.png new file mode 100644 index 0000000000..f881f60dac Binary files /dev/null and b/railties/guides/assets/images/i18n/demo_html_safe.png differ diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 4b6b08bcec..76cd14d479 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -448,6 +448,7 @@ Covered are features like these: * looking up translations * interpolating data into translations * pluralizing translations +* using safe HTML translations * localizing dates, numbers, currency, etc. h4. Looking up Translations @@ -599,6 +600,27 @@ The +I18n.locale+ defaults to +I18n.default_locale+ which defaults to :+en+. The I18n.default_locale = :de +h4. Using Safe HTML Translations + +Keys with a '_html' suffix and keys named 'html' are marked as HTML safe. Use them in views without escaping. + + +# config/locales/en.yml +en: + welcome: welcome! + hello_html: hello! + title: + html: title! + +# app/views/home/index.html.erb +
<%= t('welcome') %>
+
<%= raw t('welcome') %>
+
<%= t('hello_html') %>
+
<%= t('title.html') %>
+
+ +!images/i18n/demo_html_safe.png(i18n demo html safe)! + h3. How to Store your Custom Translations The Simple backend shipped with Active Support allows you to store translations in both plain Ruby and YAML format. [2] -- cgit v1.2.3 From bffaa888ac4a1ee60a9f93650b9184a9402eff09 Mon Sep 17 00:00:00 2001 From: Willem van Bergen Date: Thu, 15 Sep 2011 08:28:53 -0400 Subject: Custom serializers and deserializers in MessageVerifier and MessageEncryptor. By default, these classes use Marshal for serializing and deserializing messages. Unfortunately, the Marshal format is closely associated with Ruby internals and even changes between different interpreters. This makes the resulting message very hard to impossible to unserialize messages generated by these classes in other environments like node.js. This patch solves this by allowing you to set your own custom serializer and deserializer lambda functions. By default, it still uses Marshal to be backwards compatible. --- activesupport/lib/active_support/message_encryptor.rb | 8 ++++++-- activesupport/lib/active_support/message_verifier.rb | 8 ++++++-- activesupport/test/message_encryptor_test.rb | 10 +++++++++- activesupport/test/message_verifier_test.rb | 9 +++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index 4f7cd12d48..05d6790075 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -13,9 +13,13 @@ module ActiveSupport class InvalidMessage < StandardError; end OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError + attr_accessor :serializer, :deserializer + def initialize(secret, cipher = 'aes-256-cbc') @secret = secret @cipher = cipher + @serializer = lambda { |value| Marshal.dump(value) } + @deserializer = lambda { |value| Marshal.load(value) } end def encrypt(value) @@ -27,7 +31,7 @@ module ActiveSupport cipher.key = @secret cipher.iv = iv - encrypted_data = cipher.update(Marshal.dump(value)) + encrypted_data = cipher.update(serializer.call(value)) encrypted_data << cipher.final [encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--") @@ -44,7 +48,7 @@ module ActiveSupport decrypted_data = cipher.update(encrypted_data) decrypted_data << cipher.final - Marshal.load(decrypted_data) + deserializer.call(decrypted_data) rescue OpenSSLCipherError, TypeError raise InvalidMessage end diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index 8f3946325a..e38e242cfe 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -21,9 +21,13 @@ module ActiveSupport class MessageVerifier class InvalidSignature < StandardError; end + attr_accessor :serializer, :deserializer + def initialize(secret, digest = 'SHA1') @secret = secret @digest = digest + @serializer = lambda { |value| Marshal.dump(value) } + @deserializer = lambda { |value| Marshal.load(value) } end def verify(signed_message) @@ -31,14 +35,14 @@ module ActiveSupport data, digest = signed_message.split("--") if data.present? && digest.present? && secure_compare(digest, generate_digest(data)) - Marshal.load(ActiveSupport::Base64.decode64(data)) + deserializer.call(ActiveSupport::Base64.decode64(data)) else raise InvalidSignature end end def generate(value) - data = ActiveSupport::Base64.encode64s(Marshal.dump(value)) + data = ActiveSupport::Base64.encode64s(serializer.call(value)) "#{data}--#{generate_digest(data)}" end diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index e45d5ecd59..bd11b76e60 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -8,6 +8,7 @@ rescue LoadError, NameError else require 'active_support/time' +require 'active_support/json' class MessageEncryptorTest < Test::Unit::TestCase def setup @@ -38,7 +39,14 @@ class MessageEncryptorTest < Test::Unit::TestCase message = @encryptor.encrypt_and_sign(@data) assert_equal @data, @encryptor.decrypt_and_verify(message) end - + + def test_alternative_serialization_method + @encryptor.serializer = lambda { |value| ActiveSupport::JSON.encode(value) } + @encryptor.deserializer = lambda { |value| ActiveSupport::JSON.decode(value) } + + message = @encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.local(2010) }) + assert_equal @encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00-05:00" } + end private def assert_not_decrypted(value) diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index 4821311244..83f34ebc33 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -8,6 +8,7 @@ rescue LoadError, NameError else require 'active_support/time' +require 'active_support/json' class MessageVerifierTest < Test::Unit::TestCase def setup @@ -31,6 +32,14 @@ class MessageVerifierTest < Test::Unit::TestCase assert_not_verified("#{data}--#{hash.reverse}") assert_not_verified("purejunk") end + + def test_alternative_serialization_method + @verifier.serializer = lambda { |value| ActiveSupport::JSON.encode(value) } + @verifier.deserializer = lambda { |value| ActiveSupport::JSON.decode(value) } + + message = @verifier.generate({ :foo => 123, 'bar' => Time.local(2010) }) + assert_equal @verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00-05:00" } + end def assert_not_verified(message) assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do -- cgit v1.2.3 From a8aaef676217f53f2812cd56f71a6b00c5d22162 Mon Sep 17 00:00:00 2001 From: Willem van Bergen Date: Thu, 15 Sep 2011 09:50:39 -0400 Subject: Fixed tests so that they will also run properly in other timezones. --- activesupport/test/message_encryptor_test.rb | 4 ++-- activesupport/test/message_verifier_test.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index bd11b76e60..95e64fe6d1 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -44,8 +44,8 @@ class MessageEncryptorTest < Test::Unit::TestCase @encryptor.serializer = lambda { |value| ActiveSupport::JSON.encode(value) } @encryptor.deserializer = lambda { |value| ActiveSupport::JSON.decode(value) } - message = @encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.local(2010) }) - assert_equal @encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00-05:00" } + message = @encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) }) + assert_equal @encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end private diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index 83f34ebc33..224e38a52a 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -37,8 +37,8 @@ class MessageVerifierTest < Test::Unit::TestCase @verifier.serializer = lambda { |value| ActiveSupport::JSON.encode(value) } @verifier.deserializer = lambda { |value| ActiveSupport::JSON.decode(value) } - message = @verifier.generate({ :foo => 123, 'bar' => Time.local(2010) }) - assert_equal @verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00-05:00" } + message = @verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) }) + assert_equal @verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end def assert_not_verified(message) -- cgit v1.2.3 From db040cdf8ba832123bae68764189bbcb569d473a Mon Sep 17 00:00:00 2001 From: Willem van Bergen Date: Thu, 15 Sep 2011 13:15:21 -0400 Subject: Implement API suggestions of pull request. --- activesupport/lib/active_support/message_encryptor.rb | 11 +++++------ activesupport/lib/active_support/message_verifier.rb | 11 +++++------ activesupport/test/message_encryptor_test.rb | 15 ++++++++++++--- activesupport/test/message_verifier_test.rb | 15 ++++++++++++--- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index 05d6790075..66e121be26 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -13,13 +13,12 @@ module ActiveSupport class InvalidMessage < StandardError; end OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError - attr_accessor :serializer, :deserializer + attr_accessor :serializer - def initialize(secret, cipher = 'aes-256-cbc') + def initialize(secret, cipher = 'aes-256-cbc', serializer = Marshal) @secret = secret @cipher = cipher - @serializer = lambda { |value| Marshal.dump(value) } - @deserializer = lambda { |value| Marshal.load(value) } + @serializer = serializer end def encrypt(value) @@ -31,7 +30,7 @@ module ActiveSupport cipher.key = @secret cipher.iv = iv - encrypted_data = cipher.update(serializer.call(value)) + encrypted_data = cipher.update(serializer.dump(value)) encrypted_data << cipher.final [encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--") @@ -48,7 +47,7 @@ module ActiveSupport decrypted_data = cipher.update(encrypted_data) decrypted_data << cipher.final - deserializer.call(decrypted_data) + serializer.load(decrypted_data) rescue OpenSSLCipherError, TypeError raise InvalidMessage end diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index e38e242cfe..b3a087a596 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -21,13 +21,12 @@ module ActiveSupport class MessageVerifier class InvalidSignature < StandardError; end - attr_accessor :serializer, :deserializer + attr_accessor :serializer - def initialize(secret, digest = 'SHA1') + def initialize(secret, digest = 'SHA1', serializer = Marshal) @secret = secret @digest = digest - @serializer = lambda { |value| Marshal.dump(value) } - @deserializer = lambda { |value| Marshal.load(value) } + @serializer = serializer end def verify(signed_message) @@ -35,14 +34,14 @@ module ActiveSupport data, digest = signed_message.split("--") if data.present? && digest.present? && secure_compare(digest, generate_digest(data)) - deserializer.call(ActiveSupport::Base64.decode64(data)) + serializer.load(ActiveSupport::Base64.decode64(data)) else raise InvalidSignature end end def generate(value) - data = ActiveSupport::Base64.encode64s(serializer.call(value)) + data = ActiveSupport::Base64.encode64s(serializer.dump(value)) "#{data}--#{generate_digest(data)}" end diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 95e64fe6d1..9c89512b42 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -11,6 +11,17 @@ require 'active_support/time' require 'active_support/json' class MessageEncryptorTest < Test::Unit::TestCase + + class JSONSerializer + def dump(value) + ActiveSupport::JSON.encode(value) + end + + def load(value) + ActiveSupport::JSON.decode(value) + end + end + def setup @encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64)) @data = { :some => "data", :now => Time.local(2010) } @@ -41,9 +52,7 @@ class MessageEncryptorTest < Test::Unit::TestCase end def test_alternative_serialization_method - @encryptor.serializer = lambda { |value| ActiveSupport::JSON.encode(value) } - @encryptor.deserializer = lambda { |value| ActiveSupport::JSON.decode(value) } - + @encryptor.serializer = JSONSerializer.new message = @encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) }) assert_equal @encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index 224e38a52a..10a1738786 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -11,6 +11,17 @@ require 'active_support/time' require 'active_support/json' class MessageVerifierTest < Test::Unit::TestCase + + class JSONSerializer + def dump(value) + ActiveSupport::JSON.encode(value) + end + + def load(value) + ActiveSupport::JSON.decode(value) + end + end + def setup @verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!") @data = { :some => "data", :now => Time.local(2010) } @@ -34,9 +45,7 @@ class MessageVerifierTest < Test::Unit::TestCase end def test_alternative_serialization_method - @verifier.serializer = lambda { |value| ActiveSupport::JSON.encode(value) } - @verifier.deserializer = lambda { |value| ActiveSupport::JSON.decode(value) } - + @verifier.serializer = JSONSerializer.new message = @verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) }) assert_equal @verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end -- cgit v1.2.3 From 2d30d4cb888e2da7c1f0a8828b467d2e21c90cfa Mon Sep 17 00:00:00 2001 From: Willem van Bergen Date: Thu, 15 Sep 2011 13:23:08 -0400 Subject: Add some documentation for the new serializer property of MessageVerifier and MessageEncryptor. --- activesupport/lib/active_support/message_verifier.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index b3a087a596..0181070479 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -18,6 +18,11 @@ module ActiveSupport # self.current_user = User.find(id) # end # + # By default it uses Marshal to serialize the message. If you want to use another + # serialization method, you can set the serializer attribute to something that responds + # to dump and load, e.g.: + # + # @verifier.serializer = YAML class MessageVerifier class InvalidSignature < StandardError; end -- cgit v1.2.3 From 41fea0334232824d5d509a6924e8c8487d53494b Mon Sep 17 00:00:00 2001 From: Willem van Bergen Date: Thu, 15 Sep 2011 14:27:12 -0400 Subject: Use an options hash to specify digest/cipher algorithm and a serializer for MessageVerifier and MessageEncryptor. --- activesupport/lib/active_support/message_encryptor.rb | 17 ++++++++++------- activesupport/lib/active_support/message_verifier.rb | 17 ++++++++++------- activesupport/test/message_encryptor_test.rb | 6 +++--- activesupport/test/message_verifier_test.rb | 6 +++--- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index 66e121be26..7637cfe2b0 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -13,12 +13,15 @@ module ActiveSupport class InvalidMessage < StandardError; end OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError - attr_accessor :serializer - - def initialize(secret, cipher = 'aes-256-cbc', serializer = Marshal) + def initialize(secret, options = {}) + unless options.is_a?(Hash) + ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :cipher => 'algorithm' to sepcify the cipher algorithm." + options = { :cipher => options } + end + @secret = secret - @cipher = cipher - @serializer = serializer + @cipher = options[:cipher] || 'aes-256-cbc' + @serializer = options[:serializer] || Marshal end def encrypt(value) @@ -30,7 +33,7 @@ module ActiveSupport cipher.key = @secret cipher.iv = iv - encrypted_data = cipher.update(serializer.dump(value)) + encrypted_data = cipher.update(@serializer.dump(value)) encrypted_data << cipher.final [encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--") @@ -47,7 +50,7 @@ module ActiveSupport decrypted_data = cipher.update(encrypted_data) decrypted_data << cipher.final - serializer.load(decrypted_data) + @serializer.load(decrypted_data) rescue OpenSSLCipherError, TypeError raise InvalidMessage end diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index 0181070479..57317028fc 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -26,12 +26,15 @@ module ActiveSupport class MessageVerifier class InvalidSignature < StandardError; end - attr_accessor :serializer - - def initialize(secret, digest = 'SHA1', serializer = Marshal) + def initialize(secret, options = {}) + unless options.is_a?(Hash) + ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :digest => 'algorithm' to sepcify the digest algorithm." + options = { :digest => options } + end + @secret = secret - @digest = digest - @serializer = serializer + @digest = options[:digest] || 'SHA1' + @serializer = options[:serializer] || Marshal end def verify(signed_message) @@ -39,14 +42,14 @@ module ActiveSupport data, digest = signed_message.split("--") if data.present? && digest.present? && secure_compare(digest, generate_digest(data)) - serializer.load(ActiveSupport::Base64.decode64(data)) + @serializer.load(ActiveSupport::Base64.decode64(data)) else raise InvalidSignature end end def generate(value) - data = ActiveSupport::Base64.encode64s(serializer.dump(value)) + data = ActiveSupport::Base64.encode64s(@serializer.dump(value)) "#{data}--#{generate_digest(data)}" end diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 9c89512b42..58f94a7400 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -52,9 +52,9 @@ class MessageEncryptorTest < Test::Unit::TestCase end def test_alternative_serialization_method - @encryptor.serializer = JSONSerializer.new - message = @encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) }) - assert_equal @encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } + encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), :serializer => JSONSerializer.new) + message = encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) }) + assert_equal encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end private diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index 10a1738786..3dc047c126 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -45,9 +45,9 @@ class MessageVerifierTest < Test::Unit::TestCase end def test_alternative_serialization_method - @verifier.serializer = JSONSerializer.new - message = @verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) }) - assert_equal @verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } + verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", :serializer => JSONSerializer.new) + message = verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) }) + assert_equal verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end def assert_not_verified(message) -- cgit v1.2.3 From 6d520803ee005d47c876662ba426083e823199ed Mon Sep 17 00:00:00 2001 From: Willem van Bergen Date: Thu, 15 Sep 2011 15:51:30 -0400 Subject: Test deprecation warning when not using an options hash as second parameter. --- activesupport/test/message_encryptor_test.rb | 8 +++++++- activesupport/test/message_verifier_test.rb | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 58f94a7400..83a19f8106 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -10,7 +10,7 @@ else require 'active_support/time' require 'active_support/json' -class MessageEncryptorTest < Test::Unit::TestCase +class MessageEncryptorTest < ActiveSupport::TestCase class JSONSerializer def dump(value) @@ -57,6 +57,12 @@ class MessageEncryptorTest < Test::Unit::TestCase assert_equal encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end + def test_digest_algorithm_as_second_parameter_deprecation + assert_deprecated(/options hash/) do + ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), 'aes-256-cbc') + end + end + private def assert_not_decrypted(value) assert_raise(ActiveSupport::MessageEncryptor::InvalidMessage) do diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index 3dc047c126..35747abe5b 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -10,7 +10,7 @@ else require 'active_support/time' require 'active_support/json' -class MessageVerifierTest < Test::Unit::TestCase +class MessageVerifierTest < ActiveSupport::TestCase class JSONSerializer def dump(value) @@ -49,6 +49,12 @@ class MessageVerifierTest < Test::Unit::TestCase message = verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) }) assert_equal verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end + + def test_digest_algorithm_as_second_parameter_deprecation + assert_deprecated(/options hash/) do + ActiveSupport::MessageVerifier.new("secret", "SHA1") + end + end def assert_not_verified(message) assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do -- cgit v1.2.3 From b50394bf844d0520d5dca485b169bba87f6d009a Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Thu, 15 Sep 2011 19:55:52 -0500 Subject: config.action_controller.asset_host shouldn't set to nil during precompile --- actionpack/lib/sprockets/assets.rake | 3 --- railties/test/application/assets_test.rb | 14 -------------- 2 files changed, 17 deletions(-) diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake index 9b2f3a3f94..81223b7ead 100644 --- a/actionpack/lib/sprockets/assets.rake +++ b/actionpack/lib/sprockets/assets.rake @@ -17,9 +17,6 @@ namespace :assets do # Always compile files Rails.application.config.assets.compile = true - # Always ignore asset host - Rails.application.config.action_controller.asset_host = nil - config = Rails.application.config env = Rails.application.assets target = Pathname.new(File.join(Rails.public_path, config.assets.prefix)) diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index 959914bcea..dfd950aae3 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -270,20 +270,6 @@ module ApplicationTests assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file)) end - test "precompile ignore asset_host" do - app_file "app/assets/javascripts/application.css.erb", "<%= asset_path 'rails.png' %>" - add_to_config "config.action_controller.asset_host = Proc.new { |source, request| 'http://www.example.com/' }" - - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end - - file = Dir["#{app_path}/public/assets/application.css"].first - content = File.read(file) - assert_match(/\/assets\/rails.png/, content) - assert_no_match(/www\.example\.com/, content) - end - test "precompile should handle utf8 filenames" do app_file "app/assets/images/レイルズ.png", "not a image really" add_to_config "config.assets.precompile = [ /\.png$$/, /application.(css|js)$/ ]" -- cgit v1.2.3 From 28677014a4f8121272a17870246507e86e46837c Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Thu, 15 Sep 2011 20:07:01 -0500 Subject: Add reference about --skip-sprockets to Asset Pipeline Guide --- railties/guides/source/asset_pipeline.textile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index ce4eafb97c..74dfdfb540 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -25,6 +25,12 @@ In Rails 3.1, the asset pipeline is enabled by default. It can be disabled in +a config.assets.enabled = false +You can also disable it when you are creating a new application passing the --skip-sprockets parameter: + + +rails new appname --skip-sprockets + + It is recommended that you use the defaults for all new apps. -- cgit v1.2.3 From c9aac2a215d46d25556a6a0eaae1b9f85231a6b4 Mon Sep 17 00:00:00 2001 From: Peter Suschlik Date: Fri, 16 Sep 2011 09:08:53 +0300 Subject: Fix typo in deprecation warning. --- activesupport/lib/active_support/message_encryptor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index 7637cfe2b0..e14386a85d 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -15,7 +15,7 @@ module ActiveSupport def initialize(secret, options = {}) unless options.is_a?(Hash) - ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :cipher => 'algorithm' to sepcify the cipher algorithm." + ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :cipher => 'algorithm' to specify the cipher algorithm." options = { :cipher => options } end -- cgit v1.2.3 From 302e570777b1ca8f537c96628334dcbe8a94d83f Mon Sep 17 00:00:00 2001 From: Kir Shatrov Date: Fri, 16 Sep 2011 17:43:05 +0400 Subject: "Passing variables into the translation" section added --- railties/guides/source/i18n.textile | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 76cd14d479..a35cd6c506 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -365,6 +365,20 @@ NOTE: You need to restart the server when you add new locale files. You may use YAML (+.yml+) or plain Ruby (+.rb+) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.) +h4. Passing variables into the translation + +You may use translation with parameters, if you want. + + +# app/views/home/index.html.erb +

<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %>

+

<%=t 'greet_username', :user => "DHH", :message => "Hello" %>

+ +# config/locales/en.yml +en: + greet_username: "%{message}, %{user}!" +
+ h4. Adding Date/Time Formats OK! Now let's add a timestamp to the view, so we can demo the *date/time localization* feature as well. To localize the time format you pass the Time object to +I18n.l+ or (preferably) use Rails' +#l+ helper. You can pick a format by passing the +:format+ option -- by default the +:default+ format is used. -- cgit v1.2.3 From b0ae34ad72ed8410e6f16c1d9ee4b04b2630208f Mon Sep 17 00:00:00 2001 From: Claudio Poli Date: Fri, 16 Sep 2011 19:54:48 +0300 Subject: Fix typo in deprecation notice --- activesupport/lib/active_support/message_verifier.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index 57317028fc..9d7c81142a 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -28,7 +28,7 @@ module ActiveSupport def initialize(secret, options = {}) unless options.is_a?(Hash) - ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :digest => 'algorithm' to sepcify the digest algorithm." + ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :digest => 'algorithm' to specify the digest algorithm." options = { :digest => options } end -- cgit v1.2.3 From 8411f631c42de7d6f51d10d997b037b9eff0d1f1 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Fri, 16 Sep 2011 23:22:03 +0530 Subject: minor edit --- railties/guides/source/asset_pipeline.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index 74dfdfb540..bea5e494d5 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -25,7 +25,7 @@ In Rails 3.1, the asset pipeline is enabled by default. It can be disabled in +a config.assets.enabled = false -You can also disable it when you are creating a new application passing the --skip-sprockets parameter: +You can also disable it while creating a new application by passing the --skip-sprockets option. rails new appname --skip-sprockets -- cgit v1.2.3 From 27f1320fde03279c575693f504897f1a6171bc59 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Fri, 16 Sep 2011 22:12:41 +0530 Subject: Fixing incorrect notextile tags --- .../guides/source/action_view_overview.textile | 2 +- .../active_record_validations_callbacks.textile | 4 ++-- .../source/active_support_core_extensions.textile | 26 +++++++++++----------- railties/guides/source/ajax_on_rails.textile | 4 +++- .../source/api_documentation_guidelines.textile | 2 +- railties/guides/source/asset_pipeline.textile | 2 +- railties/guides/source/initialization.textile | 2 +- .../source/ruby_on_rails_guides_guidelines.textile | 2 +- railties/guides/source/security.textile | 6 ++--- 9 files changed, 26 insertions(+), 24 deletions(-) diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile index 87250c684b..40cde6ad84 100644 --- a/railties/guides/source/action_view_overview.textile +++ b/railties/guides/source/action_view_overview.textile @@ -898,7 +898,7 @@ h5. select_year Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius can be changed using the +:start_year+ and +:end_year+ keys in the +options+. -# Generates a select field for five years on either side of +Date.today+ that defaults to the current year +# Generates a select field for five years on either side of Date.today that defaults to the current year select_year(Date.today) # Generates a select field from 1900 to 2009 that defaults to the current year diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile index 20f5e52891..5c3aae2955 100644 --- a/railties/guides/source/active_record_validations_callbacks.textile +++ b/railties/guides/source/active_record_validations_callbacks.textile @@ -328,7 +328,7 @@ This helper validates that your attributes have only numeric values. By default, If you set +:only_integer+ to +true+, then it will use the -/\A[+-]?\d+\Z/ +/\A[-]?\d\Z/ regular expression to validate the attribute's value. Otherwise, it will try to convert the value to a number using +Float+. @@ -597,7 +597,7 @@ The easiest way to add custom validators for validating individual attributes is class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i + unless value =~ /\A([^@\s])@((?:[-a-z0-9]\.)+[a-z]{2,})\z/i record.errors[attribute] << (options[:message] || "is not an email") end end diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index d006cc9214..b3d8760a73 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -296,7 +296,7 @@ This method escapes whatever is needed, both for the key and the value: account.to_query('company[name]') -# => "company%5Bname%5D=Johnson+%26+Johnson" +# => "company%5Bname%5D=Johnson%26Johnson" so its output is ready to be used in a query string. @@ -3385,11 +3385,11 @@ They are analogous. Please refer to their documentation above and take into acco Time.zone_default # => # -# In Barcelona, 2010/03/28 02:00 +0100 becomes 2010/03/28 03:00 +0200 due to DST. +# In Barcelona, 2010/03/28 02:00 0100 becomes 2010/03/28 03:00 0200 due to DST. t = Time.local_time(2010, 3, 28, 1, 59, 59) -# => Sun Mar 28 01:59:59 +0100 2010 +# => Sun Mar 28 01:59:59 0100 2010 t.advance(:seconds => 1) -# => Sun Mar 28 03:00:00 +0200 2010 +# => Sun Mar 28 03:00:00 0200 2010 * If +since+ or +ago+ jump to a time that can't be expressed with +Time+ a +DateTime+ object is returned instead. @@ -3406,24 +3406,24 @@ The method +all_day+ returns a range representing the whole day of the current t now = Time.current -# => Mon, 09 Aug 2010 23:20:05 UTC +00:00 +# => Mon, 09 Aug 2010 23:20:05 UTC 00:00 now.all_day -# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00 +# => Mon, 09 Aug 2010 00:00:00 UTC 00:00..Mon, 09 Aug 2010 23:59:59 UTC 00:00 Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the purpose of generating time ranges. now = Time.current -# => Mon, 09 Aug 2010 23:20:05 UTC +00:00 +# => Mon, 09 Aug 2010 23:20:05 UTC 00:00 now.all_week -# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00 +# => Mon, 09 Aug 2010 00:00:00 UTC 00:00..Sun, 15 Aug 2010 23:59:59 UTC 00:00 now.all_month -# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00 +# => Sat, 01 Aug 2010 00:00:00 UTC 00:00..Tue, 31 Aug 2010 23:59:59 UTC 00:00 now.all_quarter -# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00 +# => Thu, 01 Jul 2010 00:00:00 UTC 00:00..Thu, 30 Sep 2010 23:59:59 UTC 00:00 now.all_year -# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00 +# => Fri, 01 Jan 2010 00:00:00 UTC 00:00..Fri, 31 Dec 2010 23:59:59 UTC 00:00 h4. Time Constructors @@ -3434,7 +3434,7 @@ Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user ti Time.zone_default # => # Time.current -# => Fri, 06 Aug 2010 17:11:58 CEST +02:00 +# => Fri, 06 Aug 2010 17:11:58 CEST 02:00 Analogously to +DateTime+, the predicates +past?+, and +future?+ are relative to +Time.current+. @@ -3445,7 +3445,7 @@ Use the +local_time+ class method to create time objects honoring the user time Time.zone_default # => # Time.local_time(2010, 8, 15) -# => Sun Aug 15 00:00:00 +0200 2010 +# => Sun Aug 15 00:00:00 0200 2010 The +utc_time+ class method returns a time in UTC: diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile index 77f7661deb..29d4fae888 100644 --- a/railties/guides/source/ajax_on_rails.textile +++ b/railties/guides/source/ajax_on_rails.textile @@ -104,7 +104,7 @@ Note that if we wouldn't override the default behavior (POST), the above snippet link_to_remote "Update record", :url => record_url(record), :method => :put, - :with => "'status=' + 'encodeURIComponent($('status').value) + '&completed=' + $('completed')" + :with => "'status=' 'encodeURIComponent($('status').value) '&completed=' $('completed')" This generates a remote link which adds 2 parameters to the standard URL generated by Rails, taken from the page (contained in the elements matched by the 'status' and 'completed' DOM id). @@ -124,6 +124,7 @@ link_to_remote "Add new item", 404 => "alert('Item not found!')" Let's see a typical example for the most frequent callbacks, +:success+, +:failure+ and +:complete+ in action: + link_to_remote "Add new item", :url => items_url, @@ -133,6 +134,7 @@ link_to_remote "Add new item", :success => "display_item_added(request)", :failure => "display_error(request)" + ** *:type* If you want to fire a synchronous request for some obscure reason (blocking the browser while the request is processed and doesn't return a status code), you can use the +:type+ option with the value of +:synchronous+. * Finally, using the +html_options+ parameter you can add HTML attributes to the generated tag. It works like the same parameter of the +link_to+ helper. There are interesting side effects for the +href+ and +onclick+ parameters though: ** If you specify the +href+ parameter, the AJAX link will degrade gracefully, i.e. the link will point to the URL even if JavaScript is disabled in the client browser diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile index c0f709eda8..99eb668513 100644 --- a/railties/guides/source/api_documentation_guidelines.textile +++ b/railties/guides/source/api_documentation_guidelines.textile @@ -146,7 +146,7 @@ h3. Description Lists In lists of options, parameters, etc. use a hyphen between the item and its description (reads better than a colon because normally options are symbols): -# * :allow_nil - Skip validation if attribute is +nil+. +# * :allow_nil - Skip validation if attribute is nil. The description starts in upper case and ends with a full stop—it's standard English. diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index bea5e494d5..e03ae736a8 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -359,7 +359,7 @@ NOTE. If you are precompiling your assets locally, you can use +bundle install - The default matcher for compiling files includes +application.js+, +application.css+ and all files that do not end in +js+ or +css+: -[ /\w+\.(?!js|css).+/, /application.(css|js)$/ ] +[ /\w\.(?!js|css)./, /application.(css|js)$/ ] If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the +precompile+ array: diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 8aabc3ae91..32b41fdd2c 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -450,7 +450,7 @@ run YourApp::Application The +Rack::Builder.parse_file+ method here takes the content from this +config.ru+ file and parses it using this code: -app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app", +app = eval "Rack::Builder.new {( " cfgfile "\n )}.to_app", TOPLEVEL_BINDING, config diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile index e63f564c83..29aefd25f8 100644 --- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile +++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile @@ -26,7 +26,7 @@ h5. When are Objects Saved? Use the same typography as in regular text: -h6. The +:content_type+ Option +h6. The :content_type Option h3. API Documentation Guidelines diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 4cf9e2a7f3..73c7a80ff6 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -582,7 +582,7 @@ Ruby uses a slightly different approach than many other languages to match the e class File < ActiveRecord::Base - validates :name, :format => /^[\w\.\-\+]+$/ + validates :name, :format => /^[\w\.\-\]$/ end @@ -595,7 +595,7 @@ file.txt%0A Whereas %0A is a line feed in URL encoding, so Rails automatically converts it to "file.txt\n<script>alert('hello')</script>". This file name passes the filter because the regular expression matches – up to the line end, the rest does not matter. The correct expression should read: -/\A[\w\.\-\+]+\z/ +/\A[\w\.\-\]\z/ h4. Privilege Escalation @@ -762,7 +762,7 @@ These examples don't do any harm so far, so let's see how an attacker can steal For an attacker, of course, this is not useful, as the victim will see his own cookie. The next example will try to load an image from the URL http://www.attacker.com/ plus the cookie. Of course this URL does not exist, so the browser displays nothing. But the attacker can review his web server's access log files to see the victim's cookie. - + The log files on www.attacker.com will read like this: -- cgit v1.2.3 From 3a04e370e4cc016bb7b59fe6bb704e4ca37d62f3 Mon Sep 17 00:00:00 2001 From: brainopia Date: Fri, 16 Sep 2011 22:59:16 +0400 Subject: Fix Hash#to_query edge case with html_safe string on 1.8 ruby --- activesupport/lib/active_support/core_ext/object/to_query.rb | 2 +- activesupport/test/core_ext/object/to_query_test.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/core_ext/object/to_query.rb b/activesupport/lib/active_support/core_ext/object/to_query.rb index 3f1540f685..5d5fcf00e0 100644 --- a/activesupport/lib/active_support/core_ext/object/to_query.rb +++ b/activesupport/lib/active_support/core_ext/object/to_query.rb @@ -7,7 +7,7 @@ class Object # Note: This method is defined as a default implementation for all Objects for Hash#to_query to work. def to_query(key) require 'cgi' unless defined?(CGI) && defined?(CGI::escape) - "#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}" + "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}" end end diff --git a/activesupport/test/core_ext/object/to_query_test.rb b/activesupport/test/core_ext/object/to_query_test.rb index 84da52f4bf..c146f6cc9b 100644 --- a/activesupport/test/core_ext/object/to_query_test.rb +++ b/activesupport/test/core_ext/object/to_query_test.rb @@ -1,6 +1,7 @@ require 'abstract_unit' require 'active_support/ordered_hash' require 'active_support/core_ext/object/to_query' +require 'active_support/core_ext/string/output_safety.rb' class ToQueryTest < Test::Unit::TestCase def test_simple_conversion @@ -11,6 +12,14 @@ class ToQueryTest < Test::Unit::TestCase assert_query_equal 'a%3Ab=c+d', 'a:b' => 'c d' end + def test_html_safe_parameter_key + assert_query_equal 'a%3Ab=c+d', 'a:b'.html_safe => 'c d' + end + + def test_html_safe_parameter_value + assert_query_equal 'a=%5B10%5D', 'a' => '[10]'.html_safe + end + def test_nil_parameter_value empty = Object.new def empty.to_param; nil end -- cgit v1.2.3 From 18116791d00d693643db3b4a99ae1d245c5a6c33 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 16 Sep 2011 17:25:40 -0700 Subject: Proper lines numbers for stack trace info --- activesupport/lib/active_support/core_ext/string/output_safety.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 05b39b89bf..3ae3d64fa4 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -142,7 +142,7 @@ module ActiveSupport #:nodoc: end UNSAFE_STRING_METHODS.each do |unsafe_method| - class_eval <<-EOT, __FILE__, __LINE__ + class_eval <<-EOT, __FILE__, __LINE__ + 1 def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) to_str.#{unsafe_method}(*args, &block) # to_str.gsub(*args, &block) end # end -- cgit v1.2.3 From 6e63e029b335b1a5dfce43c20de27ca6fae29fa4 Mon Sep 17 00:00:00 2001 From: Alex Yakoubian Date: Wed, 14 Sep 2011 23:14:23 -0700 Subject: Default precompile regexp that properly matches application.js and application.css --- railties/lib/rails/application/configuration.rb | 2 +- railties/test/application/assets_test.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index a48db3b6d2..141b39fb4b 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -38,7 +38,7 @@ module Rails @assets.enabled = false @assets.paths = [] @assets.precompile = [ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) }, - /application.(css|js)$/ ] + /(?:\/|\\|\A)application\.(css|js)$/ ] @assets.prefix = "/assets" @assets.version = '' @assets.debug = false diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index dfd950aae3..a62ef1e70e 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -68,6 +68,10 @@ module ApplicationTests test "precompile application.js and application.css and all other files not ending with .js or .css by default" do app_file "app/assets/javascripts/application.js", "alert();" app_file "app/assets/stylesheets/application.css", "body{}" + + app_file "app/assets/javascripts/someapplication.js", "alert();" + app_file "app/assets/stylesheets/someapplication.css", "body{}" + app_file "app/assets/javascripts/something.min.js", "alert();" app_file "app/assets/stylesheets/something.min.css", "body{}" @@ -87,8 +91,13 @@ module ApplicationTests images_should_compile.each do |filename| assert File.exists?("#{app_path}/public/assets/#{filename}") end + assert File.exists?("#{app_path}/public/assets/application.js") assert File.exists?("#{app_path}/public/assets/application.css") + + assert !File.exists?("#{app_path}/public/assets/someapplication.js") + assert !File.exists?("#{app_path}/public/assets/someapplication.css") + assert !File.exists?("#{app_path}/public/assets/something.min.js") assert !File.exists?("#{app_path}/public/assets/something.min.css") end -- cgit v1.2.3 From 663031801cac577a88931cdfe6f062555112f370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=A3is=20Ozols?= Date: Sat, 17 Sep 2011 10:00:53 +0300 Subject: sass-rails helpers - hyphenated in Sass, underscored in Ruby. --- railties/guides/source/asset_pipeline.textile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index e03ae736a8..586a9f46eb 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -170,15 +170,15 @@ Note that the closing tag cannot be of the style +-%>+. h5. CSS and Sass -When using the asset pipeline, paths to assets must be re-written and +sass-rails+ provides +_url+ and +_path+ helpers for the following asset classes: image, font, video, audio, JavaScript and stylesheet. +When using the asset pipeline, paths to assets must be re-written and +sass-rails+ provides +-url+ and +-path+ helpers (hyphenated in Sass, underscored in Ruby) for the following asset classes: image, font, video, audio, JavaScript and stylesheet. -* +image_url("rails.png")+ becomes +url(/assets/rails.png)+. -* +image_path("rails.png")+ becomes +"/assets/rails.png"+. +* +image-url("rails.png")+ becomes +url(/assets/rails.png)+ +* +image-path("rails.png")+ becomes +"/assets/rails.png"+. The more generic form can also be used but the asset path and class must both be specified: -* +asset_url("rails.png", image)+ becomes +url(/assets/rails.png)+. -* +asset_path("rails.png", image)+ becomes +"/assets/rails.png"+. +* +asset-url("rails.png", image)+ becomes +url(/assets/rails.png)+ +* +asset-path("rails.png", image)+ becomes +"/assets/rails.png"+ h5. JavaScript/CoffeeScript and ERB -- cgit v1.2.3 From b2bf725d795634fb2383f3a4fa5ab5e9c61c54f1 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 17 Sep 2011 18:39:30 +0530 Subject: Bump AR-JDBC version. THis version is compatible with 3.1 and above --- Gemfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 5ce420c3a3..508d083fe6 100644 --- a/Gemfile +++ b/Gemfile @@ -75,7 +75,7 @@ end platforms :jruby do gem "ruby-debug", ">= 0.10.3" gem "json" - gem "activerecord-jdbcsqlite3-adapter" + gem "activerecord-jdbcsqlite3-adapter", ">= 1.2.0" # This is needed by now to let tests work on JRuby # TODO: When the JRuby guys merge jruby-openssl in @@ -83,8 +83,8 @@ platforms :jruby do gem "jruby-openssl" group :db do - gem "activerecord-jdbcmysql-adapter" - gem "activerecord-jdbcpostgresql-adapter" + gem "activerecord-jdbcmysql-adapter", ">= 1.2.0" + gem "activerecord-jdbcpostgresql-adapter", ">= 1.2.0" end end -- cgit v1.2.3 From afa78fe327e166a6aca10111a56101f74a6a6c8a Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sun, 18 Sep 2011 00:23:48 +0530 Subject: Fixed test for JRuby. for Sqlite3 in AR-JDBC.It's Jdbc::SQLite3::VERSION --- activerecord/test/cases/query_cache_test.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index e3ad0cad90..cda30a773e 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -148,12 +148,13 @@ class QueryCacheTest < ActiveRecord::TestCase def test_cache_does_not_wrap_string_results_in_arrays require 'sqlite3/version' if current_adapter?(:SQLite3Adapter) + sqlite3_version = RUBY_PLATFORM =~ /java/ ? Jdbc::SQLite3::VERSION : SQLite3::VERSION Task.cache do # Oracle adapter returns count() as Fixnum or Float if current_adapter?(:OracleAdapter) assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") - elsif current_adapter?(:SQLite3Adapter) && SQLite3::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter) + elsif current_adapter?(:SQLite3Adapter) && sqlite3_version > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter) # Future versions of the sqlite3 adapter will return numeric assert_instance_of Fixnum, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") -- cgit v1.2.3 From 908f2616d5c2b9e26eb180859f7df529a7a59f08 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Wed, 14 Sep 2011 18:53:08 +1000 Subject: Document ActiveRecord::QueryMethods#select --- .../lib/active_record/relation/query_methods.rb | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index a11b7a3864..4468a38ee6 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -37,6 +37,35 @@ module ActiveRecord relation end + # Works in two unique ways. + # + # First: takes a block so it can be used just like Array#select. + # + # Model.scoped.select { |m| m.field == value } + # + # This will build an array of objects from the database for the scope, + # converting them into an array and iterating through them using Array#select. + # + # Second: Modifies the SELECT statement for the query so that only certain + # fields are retreived: + # + # >> Model.select(:field) + # => [#] + # + # Although in the above example it looks as though this method returns an + # array, in actual fact it returns a relation object and can have other query + # methods appended to it, such as the other methods in ActiveRecord::QueryMethods. + # + # This method will also take multiple parameters: + # + # >> Model.select(:field, :other_field, :and_one_more) + # => [#] + # + # Any attributes that do not have fields retreived by a select + # will return `nil` when the getter method for that attribute is used: + # + # >> Model.select(:field).first.other_field + # => nil def select(value = Proc.new) if block_given? to_a.select {|*block_args| value.call(*block_args) } -- cgit v1.2.3 From ea29968bcfa455d9bef8c41436b6bea669dfc06d Mon Sep 17 00:00:00 2001 From: Jan Vlnas Date: Sun, 18 Sep 2011 16:41:21 +0300 Subject: Locale code for Czech is ":cs" --- railties/guides/source/i18n.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index a35cd6c506..14ce6a19d5 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -91,7 +91,7 @@ This means, that in the +:en+ locale, the key _hello_ will map to the _Hello wor The I18n library will use *English* as a *default locale*, i.e. if you don't set a different locale, +:en+ will be used for looking up translations. -NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cz+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it. +NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cs+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it. The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you. -- cgit v1.2.3 From 51bef9d8fb0b4da7a104425ab8545e9331387743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 18 Sep 2011 09:09:01 -0700 Subject: to_xml should also rely on serializable hash. --- activemodel/lib/active_model/serializers/xml.rb | 46 +++++++--------------- .../cases/serializers/xml_serialization_test.rb | 17 ++++++++ .../active_record/serializers/xml_serializer.rb | 2 +- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb index 64dda3bcee..d61d9d7119 100644 --- a/activemodel/lib/active_model/serializers/xml.rb +++ b/activemodel/lib/active_model/serializers/xml.rb @@ -15,10 +15,10 @@ module ActiveModel class Attribute #:nodoc: attr_reader :name, :value, :type - def initialize(name, serializable, raw_value=nil) + def initialize(name, serializable, value) @name, @serializable = name, serializable - raw_value = raw_value.in_time_zone if raw_value.respond_to?(:in_time_zone) - @value = raw_value || @serializable.send(name) + value = value.in_time_zone if value.respond_to?(:in_time_zone) + @value = value @type = compute_type end @@ -49,40 +49,24 @@ module ActiveModel def initialize(serializable, options = nil) @serializable = serializable @options = options ? options.dup : {} - - @options[:only] = Array.wrap(@options[:only]).map { |n| n.to_s } - @options[:except] = Array.wrap(@options[:except]).map { |n| n.to_s } end - # To replicate the behavior in ActiveRecord#attributes, :except - # takes precedence over :only. If :only is not set - # for a N level model but is set for the N+1 level models, - # then because :except is set to a default value, the second - # level model can have both :except and :only set. So if - # :only is set, always delete :except. - def attributes_hash - attributes = @serializable.attributes - if options[:only].any? - attributes.slice(*options[:only]) - elsif options[:except].any? - attributes.except(*options[:except]) - else - attributes - end + def serializable_hash + @serializable.serializable_hash(@options.except(:include)) end - def serializable_attributes - attributes_hash.map do |name, value| - self.class::Attribute.new(name, @serializable, value) + def serializable_collection + methods = Array.wrap(options[:methods]).map(&:to_s) + serializable_hash.map do |name, value| + name = name.to_s + if methods.include?(name) + self.class::MethodAttribute.new(name, @serializable, value) + else + self.class::Attribute.new(name, @serializable, value) + end end end - def serializable_methods - Array.wrap(options[:methods]).map do |name| - self.class::MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s) - end.compact - end - def serialize require 'builder' unless defined? ::Builder @@ -114,7 +98,7 @@ module ActiveModel end def add_attributes_and_methods - (serializable_attributes + serializable_methods).each do |attribute| + serializable_collection.each do |attribute| key = ActiveSupport::XmlMini.rename_key(attribute.name, options) ActiveSupport::XmlMini.to_tag(key, attribute.value, options.merge(attribute.decorations)) diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb index a38ef8e223..fc73d9dcd8 100644 --- a/activemodel/test/cases/serializers/xml_serialization_test.rb +++ b/activemodel/test/cases/serializers/xml_serialization_test.rb @@ -33,6 +33,12 @@ class Address end end +class SerializableContact < Contact + def serializable_hash(options={}) + super(options.merge(:only => [:name, :age])) + end +end + class XmlSerializationTest < ActiveModel::TestCase def setup @contact = Contact.new @@ -96,6 +102,17 @@ class XmlSerializationTest < ActiveModel::TestCase assert_match %r{aaron stack}, @xml + assert_match %r{25}, @xml + assert_no_match %r{}, @xml + end + test "should allow skipped types" do @xml = @contact.to_xml :skip_types => true assert_match %r{25}, @xml diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb index cbfa1ad609..0e7f57aa43 100644 --- a/activerecord/lib/active_record/serializers/xml_serializer.rb +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb @@ -179,7 +179,7 @@ module ActiveRecord #:nodoc: class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc: def initialize(*args) super - options[:except] |= Array.wrap(@serializable.class.inheritance_column) + options[:except] = Array.wrap(options[:except]) | Array.wrap(@serializable.class.inheritance_column) end class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc: -- cgit v1.2.3 From d589d9f16045e535d5cefc5ae34b5d4340c17d80 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sun, 18 Sep 2011 23:20:09 +0530 Subject: fix test error when running with postgresql. This Sqlite3 should be in if block. Was giving error because sqlite3 is not loaded --- activerecord/test/cases/query_cache_test.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index cda30a773e..7feac2b920 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -147,8 +147,10 @@ class QueryCacheTest < ActiveRecord::TestCase end def test_cache_does_not_wrap_string_results_in_arrays - require 'sqlite3/version' if current_adapter?(:SQLite3Adapter) - sqlite3_version = RUBY_PLATFORM =~ /java/ ? Jdbc::SQLite3::VERSION : SQLite3::VERSION + if current_adapter?(:SQLite3Adapter) + require 'sqlite3/version' + sqlite3_version = RUBY_PLATFORM =~ /java/ ? Jdbc::SQLite3::VERSION : SQLite3::VERSION + end Task.cache do # Oracle adapter returns count() as Fixnum or Float -- cgit v1.2.3 From 8e3d26733b8eb05e09c52c4533db6c2cfe8b07eb Mon Sep 17 00:00:00 2001 From: brainopia Date: Sun, 18 Sep 2011 23:37:27 +0400 Subject: Fix test to reflect use of to_param for keys --- activesupport/test/core_ext/hash_ext_test.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index 1813ba2a4d..fa800eada2 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -9,7 +9,7 @@ require 'active_support/inflections' class HashExtTest < Test::Unit::TestCase class IndifferentHash < HashWithIndifferentAccess end - + class SubclassingArray < Array end @@ -272,14 +272,14 @@ class HashExtTest < Test::Unit::TestCase hash = { "urls" => { "url" => [ { "address" => "1" }, { "address" => "2" } ] }}.with_indifferent_access assert_equal "1", hash[:urls][:url].first[:address] end - + def test_should_preserve_array_subclass_when_value_is_array array = SubclassingArray.new array << { "address" => "1" } hash = { "urls" => { "url" => array }}.with_indifferent_access assert_equal SubclassingArray, hash[:urls][:url].class end - + def test_should_preserve_array_class_when_hash_value_is_frozen_array array = SubclassingArray.new array << { "address" => "1" } @@ -543,7 +543,7 @@ class HashExtToParamTests < Test::Unit::TestCase end def test_to_param_hash - assert_equal 'custom2=param2-1&custom=param-1', {ToParam.new('custom') => ToParam.new('param'), ToParam.new('custom2') => ToParam.new('param2')}.to_param + assert_equal 'custom-1=param-1&custom2-1=param2-1', {ToParam.new('custom') => ToParam.new('param'), ToParam.new('custom2') => ToParam.new('param2')}.to_param end def test_to_param_hash_escapes_its_keys_and_values @@ -955,13 +955,13 @@ class HashToXmlTest < Test::Unit::TestCase hash = Hash.from_xml(xml) assert_equal "bacon is the best", hash['blog']['name'] end - + def test_empty_cdata_from_xml xml = "" - + assert_equal "", Hash.from_xml(xml)["data"] end - + def test_xsd_like_types_from_xml bacon_xml = <<-EOT @@ -1004,7 +1004,7 @@ class HashToXmlTest < Test::Unit::TestCase assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"] end - + def test_should_use_default_value_for_unknown_key hash_wia = HashWithIndifferentAccess.new(3) assert_equal 3, hash_wia[:new_key] -- cgit v1.2.3 From 7ed97bc8149f745317a897304c8c86f0e3bba4d2 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Tue, 20 Sep 2011 19:33:01 +0530 Subject: remove unnecessary markup --- .../guides/source/active_support_core_extensions.textile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index b3d8760a73..e81fe13010 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -3387,9 +3387,9 @@ Time.zone_default # In Barcelona, 2010/03/28 02:00 0100 becomes 2010/03/28 03:00 0200 due to DST. t = Time.local_time(2010, 3, 28, 1, 59, 59) -# => Sun Mar 28 01:59:59 0100 2010 +# => Sun Mar 28 01:59:59 +0100 2010 t.advance(:seconds => 1) -# => Sun Mar 28 03:00:00 0200 2010 +# => Sun Mar 28 03:00:00 +0200 2010 * If +since+ or +ago+ jump to a time that can't be expressed with +Time+ a +DateTime+ object is returned instead. @@ -3406,7 +3406,7 @@ The method +all_day+ returns a range representing the whole day of the current t now = Time.current -# => Mon, 09 Aug 2010 23:20:05 UTC 00:00 +# => Mon, 09 Aug 2010 23:20:05 UTC +00:00 now.all_day # => Mon, 09 Aug 2010 00:00:00 UTC 00:00..Mon, 09 Aug 2010 23:59:59 UTC 00:00 @@ -3415,7 +3415,7 @@ Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the now = Time.current -# => Mon, 09 Aug 2010 23:20:05 UTC 00:00 +# => Mon, 09 Aug 2010 23:20:05 UTC +00:00 now.all_week # => Mon, 09 Aug 2010 00:00:00 UTC 00:00..Sun, 15 Aug 2010 23:59:59 UTC 00:00 now.all_month @@ -3434,7 +3434,7 @@ Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user ti Time.zone_default # => # Time.current -# => Fri, 06 Aug 2010 17:11:58 CEST 02:00 +# => Fri, 06 Aug 2010 17:11:58 CEST +02:00 Analogously to +DateTime+, the predicates +past?+, and +future?+ are relative to +Time.current+. @@ -3445,7 +3445,7 @@ Use the +local_time+ class method to create time objects honoring the user time Time.zone_default # => # Time.local_time(2010, 8, 15) -# => Sun Aug 15 00:00:00 0200 2010 +# => Sun Aug 15 00:00:00 +0200 2010 The +utc_time+ class method returns a time in UTC: -- cgit v1.2.3 From ed1ada84ac5b443ef979c14a4d0f1a8a57fe9ab9 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Tue, 20 Sep 2011 19:39:46 +0530 Subject: copy edits 908f2616 --- activerecord/lib/active_record/relation/query_methods.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 4468a38ee6..670ba0987d 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -47,21 +47,21 @@ module ActiveRecord # converting them into an array and iterating through them using Array#select. # # Second: Modifies the SELECT statement for the query so that only certain - # fields are retreived: + # fields are retrieved: # # >> Model.select(:field) # => [#] # # Although in the above example it looks as though this method returns an - # array, in actual fact it returns a relation object and can have other query + # array, it actually returns a relation object and can have other query # methods appended to it, such as the other methods in ActiveRecord::QueryMethods. # # This method will also take multiple parameters: # # >> Model.select(:field, :other_field, :and_one_more) - # => [#] + # => [#] # - # Any attributes that do not have fields retreived by a select + # Any attributes that do not have fields retrieved by a select # will return `nil` when the getter method for that attribute is used: # # >> Model.select(:field).first.other_field -- cgit v1.2.3 From 5684ecf74966d81e6fa7193689881b5243cbbc39 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Tue, 20 Sep 2011 19:47:33 +0530 Subject: copy edits 302e5707 --- railties/guides/source/i18n.textile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 14ce6a19d5..11e1473ba2 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -365,14 +365,13 @@ NOTE: You need to restart the server when you add new locale files. You may use YAML (+.yml+) or plain Ruby (+.rb+) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.) -h4. Passing variables into the translation +h4. Passing variables to translations -You may use translation with parameters, if you want. +You can use variables in the translation messages and pass their values from the view. # app/views/home/index.html.erb -

<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %>

-

<%=t 'greet_username', :user => "DHH", :message => "Hello" %>

+<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %> # config/locales/en.yml en: -- cgit v1.2.3 From 857d20efdab98cf56b777e034e1f150187c5fe9a Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Tue, 20 Sep 2011 02:12:29 -0500 Subject: Move precompile task to Sprockets::StaticCompiler --- actionpack/lib/sprockets/assets.rake | 24 ++----------- actionpack/lib/sprockets/railtie.rb | 1 + actionpack/lib/sprockets/static_compiler.rb | 53 +++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 actionpack/lib/sprockets/static_compiler.rb diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake index 81223b7ead..e38ac6b489 100644 --- a/actionpack/lib/sprockets/assets.rake +++ b/actionpack/lib/sprockets/assets.rake @@ -20,30 +20,10 @@ namespace :assets do config = Rails.application.config env = Rails.application.assets target = Pathname.new(File.join(Rails.public_path, config.assets.prefix)) - manifest = {} manifest_path = config.assets.manifest || target - config.assets.precompile.each do |path| - env.each_logical_path do |logical_path| - if path.is_a?(Regexp) - next unless path.match(logical_path) - elsif path.is_a?(Proc) - next unless path.call(logical_path) - else - next unless File.fnmatch(path.to_s, logical_path) - end - - if asset = env.find_asset(logical_path) - asset_path = config.assets.digest ? asset.digest_path : logical_path - manifest[logical_path] = asset_path - filename = target.join(asset_path) - - mkdir_p filename.dirname - asset.write_to(filename) - asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/ - end - end - end + static_compiler = Sprockets::StaticCompiler.new(env, target, :digest => config.assets.digest) + manifest = static_compiler.precompile(config.assets.precompile) File.open("#{manifest_path}/manifest.yml", 'wb') do |f| YAML.dump(manifest, f) diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index f05d835554..9b31604dbe 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -2,6 +2,7 @@ module Sprockets autoload :Helpers, "sprockets/helpers" autoload :LazyCompressor, "sprockets/compressors" autoload :NullCompressor, "sprockets/compressors" + autoload :StaticCompiler, "sprockets/static_compiler" # TODO: Get rid of config.assets.enabled class Railtie < ::Rails::Railtie diff --git a/actionpack/lib/sprockets/static_compiler.rb b/actionpack/lib/sprockets/static_compiler.rb new file mode 100644 index 0000000000..fa4f9451df --- /dev/null +++ b/actionpack/lib/sprockets/static_compiler.rb @@ -0,0 +1,53 @@ +require 'fileutils' +require 'pathname' + +module Sprockets + class StaticCompiler + attr_accessor :env, :target, :digest + + def initialize(env, target, options = {}) + @env = env + @target = target + @digest = options.key?(:digest) ? options.delete(:digest) : true + end + + def precompile(paths) + Rails.application.config.assets.digest = digest + manifest = {} + + env.each_logical_path do |logical_path| + next unless precompile_path?(logical_path, paths) + if asset = env.find_asset(logical_path) + manifest[logical_path] = compile(asset) + end + end + manifest + end + + def compile(asset) + asset_path = digest_asset(asset) + filename = target.join(asset_path) + FileUtils.mkdir_p filename.dirname + asset.write_to(filename) + asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/ + asset_path + end + + def precompile_path?(logical_path, paths) + paths.each do |path| + if path.is_a?(Regexp) + return true if path.match(logical_path) + elsif path.is_a?(Proc) + return true if path.call(logical_path) + else + return true if File.fnmatch(path.to_s, logical_path) + end + end + false + end + + def digest_asset(asset) + digest ? asset.digest_path : asset.logical_path + end + end +end -- cgit v1.2.3 From 952bccd1abe142c214605897a14682ae29a16adc Mon Sep 17 00:00:00 2001 From: Waynn Lue Date: Wed, 21 Sep 2011 01:23:58 -0700 Subject: add "the" to mirror the structure of the other two points --- railties/README.rdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/README.rdoc b/railties/README.rdoc index 501541eb06..95c43045b0 100644 --- a/railties/README.rdoc +++ b/railties/README.rdoc @@ -6,7 +6,7 @@ Railties is responsible for gluing all frameworks together. Overall, it: * manages the +rails+ command line interface; -* and provides Rails generators core. +* and provides the Rails generators core. == Download -- cgit v1.2.3 From 564d7edf690ab60e439df7d7dfebc5144d8d1867 Mon Sep 17 00:00:00 2001 From: Waynn Lue Date: Wed, 21 Sep 2011 01:28:59 -0700 Subject: add a '.' to etc --- railties/guides/source/i18n.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 11e1473ba2..81d2ba9a56 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -12,7 +12,7 @@ So, in the process of _internationalizing_ your Rails application you have to: In the process of _localizing_ your application you'll probably want to do the following three things: -* Replace or supplement Rails' default locale -- e.g. date and time formats, month names, Active Record model names, etc +* Replace or supplement Rails' default locale -- e.g. date and time formats, month names, Active Record model names, etc. * Abstract strings in your application into keyed dictionaries -- e.g. flash messages, static text in your views, etc. * Store the resulting dictionaries somewhere -- cgit v1.2.3 From 3c5340ec9cbf12d19e734289ba748186af492d60 Mon Sep 17 00:00:00 2001 From: Waynn Lue Date: Wed, 21 Sep 2011 02:10:07 -0700 Subject: add a missing "on" and remove the "endprologue" text --- railties/guides/source/i18n.textile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 81d2ba9a56..46f6942d02 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -16,9 +16,7 @@ In the process of _localizing_ your application you'll probably want to do the f * Abstract strings in your application into keyed dictionaries -- e.g. flash messages, static text in your views, etc. * Store the resulting dictionaries somewhere -This guide will walk you through the I18n API and contains a tutorial how to internationalize a Rails application from the start. - -endprologue. +This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start. NOTE: The Ruby I18n framework provides you with all necessary means for internationalization/localization of your Rails application. You may, however, use any of various plugins and extensions available, which add additional functionality or features. See the Rails "I18n Wiki":http://rails-i18n.org/wiki for more information. -- cgit v1.2.3 From 8d7aee71738fbf1ff090ff44a09624e592b94b04 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 21 Sep 2011 02:19:44 +0530 Subject: indentation fixes --- railties/guides/source/active_support_core_extensions.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index e81fe13010..5aee001545 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -3518,8 +3518,8 @@ h4. +around_[level]+ Takes two arguments, a +before_message+ and +after_message+ and calls the current level method on the +Logger+ instance, passing in the +before_message+, then the specified message, then the +after_message+: - logger = Logger.new("log/development.log") - logger.around_info("before", "after") { |logger| logger.info("during") } +logger = Logger.new("log/development.log") +logger.around_info("before", "after") { |logger| logger.info("during") } h4. +silence+ -- cgit v1.2.3 From 3e80462b95808457eb1584195909e26887a1a40d Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 21 Sep 2011 19:28:36 +0530 Subject: Revert "add a missing "on" and remove the "endprologue" text" This reverts commit 3c5340ec9cbf12d19e734289ba748186af492d60. Reason: endprologue should not have been removed. --- railties/guides/source/i18n.textile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 46f6942d02..81d2ba9a56 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -16,7 +16,9 @@ In the process of _localizing_ your application you'll probably want to do the f * Abstract strings in your application into keyed dictionaries -- e.g. flash messages, static text in your views, etc. * Store the resulting dictionaries somewhere -This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start. +This guide will walk you through the I18n API and contains a tutorial how to internationalize a Rails application from the start. + +endprologue. NOTE: The Ruby I18n framework provides you with all necessary means for internationalization/localization of your Rails application. You may, however, use any of various plugins and extensions available, which add additional functionality or features. See the Rails "I18n Wiki":http://rails-i18n.org/wiki for more information. -- cgit v1.2.3 From 8aa537c9452d40aeaf25e6d7e0c5bb1205b05d1a Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Thu, 22 Sep 2011 02:13:04 +0530 Subject: fix incorrect comment --- activesupport/lib/active_support/core_ext/string/output_safety.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 3ae3d64fa4..94999807dd 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -144,7 +144,7 @@ module ActiveSupport #:nodoc: UNSAFE_STRING_METHODS.each do |unsafe_method| class_eval <<-EOT, __FILE__, __LINE__ + 1 def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) - to_str.#{unsafe_method}(*args, &block) # to_str.gsub(*args, &block) + to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block) end # end def #{unsafe_method}!(*args) # def capitalize!(*args) -- cgit v1.2.3 From f373f296d0347f025402049d94901d57987e226c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 21 Sep 2011 15:28:05 -0700 Subject: Slightly reorganize lookup context modules in order to better isolate cache responsibilities. --- actionpack/lib/action_view/lookup_context.rb | 211 ++++++++++++++------------- 1 file changed, 111 insertions(+), 100 deletions(-) diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 9ec410ac2b..a119df003a 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/module/remove_method' module ActionView # = Action View Lookup Context @@ -17,12 +18,11 @@ module ActionView mattr_accessor :registered_details self.registered_details = [] - mattr_accessor :registered_detail_setters - self.registered_detail_setters = [] - def self.register_detail(name, options = {}, &block) self.registered_details << name - self.registered_detail_setters << [name, "#{name}="] + + initialize = registered_details.map { |n| "self.#{n} = details[:#{n}]" } + update = registered_details.map { |n| "self.#{n} = details[:#{n}] if details.key?(:#{n})" } Accessors.send :define_method, :"_#{name}_defaults", &block Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1 @@ -34,6 +34,16 @@ module ActionView value = Array.wrap(value.presence || _#{name}_defaults) _set_detail(:#{name}, value) if value != @details[:#{name}] end + + remove_possible_method :initialize_details + def initialize_details(details) + #{initialize.join("\n")} + end + + remove_possible_method :update_details + def update_details(details) + #{update.join("\n")} + end METHOD end @@ -60,18 +70,53 @@ module ActionView end end - def initialize(view_paths, details = {}, prefixes = []) - @details, @details_key = { :handlers => default_handlers }, nil - @frozen_formats, @skip_default_locale = false, false - @cache = true - @prefixes = prefixes + # Add caching behavior on top of Details. + module DetailsCache + attr_accessor :cache - self.view_paths = view_paths - self.registered_detail_setters.each do |key, setter| - send(setter, details[key]) + # Calculate the details key. Remove the handlers from calculation to improve performance + # since the user cannot modify it explicitly. + def details_key #:nodoc: + @details_key ||= DetailsKey.get(@details) if @cache + end + + # Temporary skip passing the details_key forward. + def disable_cache + old_value, @cache = @cache, false + yield + ensure + @cache = old_value + end + + # Update the details keys by merging the given hash into the current + # details hash. If a block is given, the details are modified just during + # the execution of the block and reverted to the previous value after. + def update_details(new_details) + if block_given? + old_details = @details.dup + super + + begin + yield + ensure + @details_key = nil + @details = old_details + end + else + super + end + end + + protected + + def _set_detail(key, value) + @details_key = nil + @details = @details.dup if @details.frozen? + @details[key] = value.freeze end end + # Helpers related to template lookup using the lookup context information. module ViewPaths attr_reader :view_paths @@ -141,111 +186,77 @@ module ActionView end end - module Details - attr_accessor :cache - - # Calculate the details key. Remove the handlers from calculation to improve performance - # since the user cannot modify it explicitly. - def details_key #:nodoc: - @details_key ||= DetailsKey.get(@details) if @cache - end - - # Temporary skip passing the details_key forward. - def disable_cache - old_value, @cache = @cache, false - yield - ensure - @cache = old_value - end + include Accessors + include DetailsCache + include ViewPaths - # Freeze the current formats in the lookup context. By freezing them, you are guaranteeing - # that next template lookups are not going to modify the formats. The controller can also - # use this, to ensure that formats won't be further modified (as it does in respond_to blocks). - def freeze_formats(formats, unless_frozen=false) #:nodoc: - return if unless_frozen && @frozen_formats - self.formats = formats - @frozen_formats = true - end + def initialize(view_paths, details = {}, prefixes = []) + @details, @details_key = { :handlers => default_handlers }, nil + @frozen_formats, @skip_default_locale = false, false + @cache = true + @prefixes = prefixes - # Overload formats= to expand ["*/*"] values and automatically - # add :html as fallback to :js. - def formats=(values) - if values - values.concat(_formats_defaults) if values.delete "*/*" - values << :html if values == [:js] - end - super(values) - end + self.view_paths = view_paths + initialize_details(details) + end - # Do not use the default locale on template lookup. - def skip_default_locale! - @skip_default_locale = true - self.locale = nil - end + # Freeze the current formats in the lookup context. By freezing them, you + # that next template lookups are not going to modify the formats. The con + # use this, to ensure that formats won't be further modified (as it does + def freeze_formats(formats, unless_frozen=false) #:nodoc: + return if unless_frozen && @frozen_formats + self.formats = formats + @frozen_formats = true + end - # Overload locale to return a symbol instead of array. - def locale - @details[:locale].first + # Override formats= to expand ["*/*"] values and automatically + # add :html as fallback to :js. + def formats=(values) + if values + values.concat(_formats_defaults) if values.delete "*/*" + values << :html if values == [:js] end + super(values) + end - # Overload locale= to also set the I18n.locale. If the current I18n.config object responds - # to original_config, it means that it's has a copy of the original I18n configuration and it's - # acting as proxy, which we need to skip. - def locale=(value) - if value - config = I18n.config.respond_to?(:original_config) ? I18n.config.original_config : I18n.config - config.locale = value - end - - super(@skip_default_locale ? I18n.locale : _locale_defaults) - end + # Do not use the default locale on template lookup. + def skip_default_locale! + @skip_default_locale = true + self.locale = nil + end - # A method which only uses the first format in the formats array for layout lookup. - # This method plays straight with instance variables for performance reasons. - def with_layout_format - if formats.size == 1 - yield - else - old_formats = formats - _set_detail(:formats, formats[0,1]) + # Override locale to return a symbol instead of array. + def locale + @details[:locale].first + end - begin - yield - ensure - _set_detail(:formats, old_formats) - end - end + # Overload locale= to also set the I18n.locale. If the current I18n.config object responds + # to original_config, it means that it's has a copy of the original I18n configuration and it's + # acting as proxy, which we need to skip. + def locale=(value) + if value + config = I18n.config.respond_to?(:original_config) ? I18n.config.original_config : I18n.config + config.locale = value end - # Update the details keys by merging the given hash into the current - # details hash. If a block is given, the details are modified just during - # the execution of the block and reverted to the previous value after. - def update_details(new_details) - old_details = @details.dup + super(@skip_default_locale ? I18n.locale : _locale_defaults) + end - registered_detail_setters.each do |key, setter| - send(setter, new_details[key]) if new_details.key?(key) - end + # A method which only uses the first format in the formats array for layout lookup. + # This method plays straight with instance variables for performance reasons. + def with_layout_format + if formats.size == 1 + yield + else + old_formats = formats + _set_detail(:formats, formats[0,1]) begin yield ensure - @details_key = nil - @details = old_details + _set_detail(:formats, old_formats) end end - - protected - - def _set_detail(key, value) - @details_key = nil - @details = @details.dup if @details.frozen? - @details[key] = value.freeze - end end - - include Accessors - include Details - include ViewPaths end end -- cgit v1.2.3 From 007f56701102647088673d92b165c3d862fbba22 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 21 Sep 2011 20:51:30 -0300 Subject: Add jquery-rails to Gemfile of plugins, test/dummy app uses it. Closes #3091 --- railties/lib/rails/generators/rails/plugin_new/templates/Gemfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile index 160baa6906..f4efd3af74 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile @@ -5,6 +5,9 @@ source "http://rubygems.org" # development dependencies will be added by default to the :development group. gemspec +# jquery-rails is used by the dummy application +gem "jquery-rails" + # Declare any dependencies that are still in development here instead of in # your gemspec. These might include edge Rails or gems from your path or # Git. Remember to move these dependencies to your gemspec before releasing @@ -17,4 +20,4 @@ gemspec <% end -%> # To use debugger -# <%= ruby_debugger_gemfile_entry %> \ No newline at end of file +# <%= ruby_debugger_gemfile_entry %> -- cgit v1.2.3 From efb8a7a7b928c8075a20ea46d9ac657ef56a7faa Mon Sep 17 00:00:00 2001 From: Christopher Arrowsmith Date: Thu, 22 Sep 2011 01:18:22 +0100 Subject: Changed "en-UK" to "en-GB" Signed-off-by: Christopher Arrowsmith --- railties/guides/source/i18n.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 81d2ba9a56..45a069b0a3 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -91,7 +91,7 @@ This means, that in the +:en+ locale, the key _hello_ will map to the _Hello wor The I18n library will use *English* as a *default locale*, i.e. if you don't set a different locale, +:en+ will be used for looking up translations. -NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cs+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it. +NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-GB+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cs+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-GB+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-GB+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it. The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you. -- cgit v1.2.3 From 8d63678d1406c5518d437709af0fde717c0248d7 Mon Sep 17 00:00:00 2001 From: Philippe Huibonhoa Date: Wed, 21 Sep 2011 21:00:46 -0700 Subject: Fixed issue in file store where it could create a filename that was too long for the file system. (https://github.com/rails/rails/issues/3072) --- activesupport/lib/active_support/cache/file_store.rb | 17 ++++++++--------- activesupport/test/caching_test.rb | 9 +++++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index f7c01948b4..ab2382d98c 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -13,6 +13,7 @@ module ActiveSupport attr_reader :cache_path DIR_FORMATTER = "%03X" + FILENAME_MAX_SIZE = 230 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write) def initialize(cache_path, options = nil) super(options) @@ -129,15 +130,13 @@ module ActiveSupport hash, dir_1 = hash.divmod(0x1000) dir_2 = hash.modulo(0x1000) fname_paths = [] - # Make sure file name is < 255 characters so it doesn't exceed file system limits. - if fname.size <= 255 - fname_paths << fname - else - while fname.size <= 255 - fname_path << fname[0, 255] - fname = fname[255, -1] - end - end + + # Make sure file name doesn't exceed file system limits. + begin + fname_paths << fname[0...FILENAME_MAX_SIZE] + fname = fname[FILENAME_MAX_SIZE..-1] + end until fname.blank? + File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, *fname_paths) end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 6bb13ec9b8..6b113594cc 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -557,6 +557,15 @@ class FileStoreTest < ActiveSupport::TestCase key = @cache_with_pathname.send(:key_file_path, "views/index?id=1") assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key) end + + # Because file systems have a maximum filename size, filenames > max size should be split in to directories + # If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B + def test_key_transformation_max_filename_size + key = "#{'A' * ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}B" + path = @cache.send(:key_file_path, key) + assert path.split('/').all? { |dir_name| dir_name.size <= ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE} + assert_equal 'B', File.basename(path) + end end class MemoryStoreTest < ActiveSupport::TestCase -- cgit v1.2.3 From a0352a425f4995f7f1e1035290fe59c93ac0d24f Mon Sep 17 00:00:00 2001 From: Philippe Huibonhoa Date: Wed, 21 Sep 2011 21:03:59 -0700 Subject: =?UTF-8?q?Updated=20existing=20test=20that=20fails=20with=20this?= =?UTF-8?q?=20fix=20(8d63678d1406c5518d437709af0fde717c0248d7).=20=20Befor?= =?UTF-8?q?e=20the=20fix=20the=20test=20was=20giving=20a=20false=20positiv?= =?UTF-8?q?e,=20because=20file=5Fstore.key=5Ffile=5Fpath=20would=20return?= =?UTF-8?q?=20an=20empty=20filename=20(i.e.=20test/tmp=5Fcache/4D0/F4D=20r?= =?UTF-8?q?ather=20than=20test/tmp=5Fcache/4D0/F4D/xxxx=E2=80=A6).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even though the fix referenced above divides the filename into directories to prevent it from being too long, it seems that 1000 characters will always raise an error, so reducing the key size to 900). --- activesupport/test/caching_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 6b113594cc..b692a41312 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -357,7 +357,7 @@ module CacheStoreBehavior def test_really_long_keys key = "" - 1000.times{key << "x"} + 900.times{key << "x"} assert_equal true, @cache.write(key, "bar") assert_equal "bar", @cache.read(key) assert_equal "bar", @cache.fetch(key) -- cgit v1.2.3 From 019eea4a388442a004287ad2e73772f3fefc7028 Mon Sep 17 00:00:00 2001 From: Pawel Pierzchala Date: Wed, 21 Sep 2011 18:12:55 +0200 Subject: Fix named routes modifying arguments --- actionpack/lib/action_dispatch/routing/route_set.rb | 7 ++++--- actionpack/test/dispatch/routing_test.rb | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 46a68a32ae..e921269331 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -165,13 +165,14 @@ module ActionDispatch remove_possible_method :#{selector} def #{selector}(*args) options = args.extract_options! + result = #{options.inspect} if args.any? - options[:_positional_args] = args - options[:_positional_keys] = #{route.segment_keys.inspect} + result[:_positional_args] = args + result[:_positional_keys] = #{route.segment_keys.inspect} end - options ? #{options.inspect}.merge(options) : #{options.inspect} + result.merge(options) end protected :#{selector} END_EVAL diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 9685b24c1c..c0b74bc9f9 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -863,6 +863,17 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal original_options, options end + # tests the arguments modification free version of define_hash_access + def test_named_route_with_no_side_effects + original_options = { :host => 'test.host' } + options = original_options.dup + + profile_customer_url("customer_model", options) + + # verify that the options passed in have not changed from the original ones + assert_equal original_options, options + end + def test_projects_status with_test_routes do assert_equal '/projects/status', url_for(:controller => 'projects', :action => 'status', :only_path => true) -- cgit v1.2.3 From 1ca3fbfbf2dfc9b2bff46ca680a89e005a1fc2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 22 Sep 2011 12:26:27 +0200 Subject: No need to recalculate the @details_key after update_details. --- actionpack/lib/action_view/lookup_context.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index a119df003a..a1fa1c0b6f 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -93,14 +93,13 @@ module ActionView # the execution of the block and reverted to the previous value after. def update_details(new_details) if block_given? - old_details = @details.dup + old_details, old_key = @details.dup, @details_key super begin yield ensure - @details_key = nil - @details = old_details + @details, @details_key = old_details, old_key end else super -- cgit v1.2.3 From 41bca5d4667a49666fc5a80bebd91f27099d1674 Mon Sep 17 00:00:00 2001 From: Nick Sutterer Date: Thu, 22 Sep 2011 13:52:52 +0200 Subject: Add rake test:template. --- actionpack/Rakefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 66dd88f0c6..d9e3e56fcc 100755 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -26,6 +26,11 @@ namespace :test do Rake::TestTask.new(:isolated) do |t| t.pattern = 'test/ts_isolated.rb' end + + Rake::TestTask.new(:template) do |t| + t.libs << 'test' + t.pattern = 'test/template/**/*.rb' + end end desc 'ActiveRecord Integration Tests' -- cgit v1.2.3 From cbaad674f13067c52fa8c1a24dc498e570db4eed Mon Sep 17 00:00:00 2001 From: Nick Sutterer Date: Thu, 22 Sep 2011 11:54:13 +0200 Subject: it is now possible to pass details options (:formats, :details, :locales, ...) to #render, #find_template and friends. this doesn't change anything in global context. --- actionpack/lib/action_view/lookup_context.rb | 24 ++++++++++++++-------- .../lib/action_view/renderer/template_renderer.rb | 5 +++-- actionpack/test/fixtures/comments/empty.html.erb | 1 + actionpack/test/fixtures/comments/empty.xml.erb | 1 + actionpack/test/template/render_test.rb | 6 ++++++ 5 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 actionpack/test/fixtures/comments/empty.html.erb create mode 100644 actionpack/test/fixtures/comments/empty.xml.erb diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index a1fa1c0b6f..96ef7da01b 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -125,17 +125,17 @@ module ActionView @view_paths = ActionView::PathSet.new(Array.wrap(paths)) end - def find(name, prefixes = [], partial = false, keys = []) - @view_paths.find(*args_for_lookup(name, prefixes, partial, keys)) + def find(name, prefixes = [], partial = false, keys = [], options = {}) + @view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options)) end alias :find_template :find - def find_all(name, prefixes = [], partial = false, keys = []) - @view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys)) + def find_all(name, prefixes = [], partial = false, keys = [], options = {}) + @view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options)) end - def exists?(name, prefixes = [], partial = false, keys = []) - @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys)) + def exists?(name, prefixes = [], partial = false, keys = [], options = {}) + @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options)) end alias :template_exists? :exists? @@ -154,9 +154,17 @@ module ActionView protected - def args_for_lookup(name, prefixes, partial, keys) #:nodoc: + def args_for_lookup(name, prefixes, partial, keys, details_options) #:nodoc: name, prefixes = normalize_name(name, prefixes) - [name, prefixes, partial || false, @details, details_key, keys] + details, details_key = detail_args_for(details_options) + [name, prefixes, partial || false, details, details_key, keys] + end + + # Compute details hash and key according to user options (e.g. passed from #render). + def detail_args_for(options) + return @details, details_key if options.empty? # most common path. + user_details = @details.merge(options) + [user_details, DetailsKey.get(user_details)] end # Support legacy foo.erb names even though we now ignore .erb diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb index d04c00fd40..0a5b470a82 100644 --- a/actionpack/lib/action_view/renderer/template_renderer.rb +++ b/actionpack/lib/action_view/renderer/template_renderer.rb @@ -15,12 +15,13 @@ module ActionView # Determine the template to be rendered using the given options. def determine_template(options) #:nodoc: - keys = options[:locals].try(:keys) || [] + keys = options[:locals].try(:keys) || [] + details = options.slice(:formats, :locale, :handlers) if options.key?(:text) Template::Text.new(options[:text], formats.try(:first)) elsif options.key?(:file) - with_fallbacks { find_template(options[:file], nil, false, keys) } + with_fallbacks { find_template(options[:file], nil, false, keys, details) } elsif options.key?(:inline) handler = Template.handler_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, :locals => keys) diff --git a/actionpack/test/fixtures/comments/empty.html.erb b/actionpack/test/fixtures/comments/empty.html.erb new file mode 100644 index 0000000000..827f3861de --- /dev/null +++ b/actionpack/test/fixtures/comments/empty.html.erb @@ -0,0 +1 @@ +

No Comment

\ No newline at end of file diff --git a/actionpack/test/fixtures/comments/empty.xml.erb b/actionpack/test/fixtures/comments/empty.xml.erb new file mode 100644 index 0000000000..db1027cd7d --- /dev/null +++ b/actionpack/test/fixtures/comments/empty.xml.erb @@ -0,0 +1 @@ +No Comment \ No newline at end of file diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 8a582030f6..525ef0d726 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -32,6 +32,12 @@ module RenderTestCases assert_equal "Hello world!", @view.render(:file => "test/hello_world") end + # Test if :formats, :locale etc. options are passed correctly to the resolvers. + def test_render_file_with_format + assert_equal "

No Comment

", @view.render(:file => "comments/empty", :formats => [:html]) + assert_equal "No Comment", @view.render(:file => "comments/empty", :formats => [:xml]) + end + def test_render_file_with_localization old_locale, @view.locale = @view.locale, :da assert_equal "Hey verden", @view.render(:file => "test/hello_world") -- cgit v1.2.3 From 119e9e2dafb0cdc5b85613b730333679aef534af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 22 Sep 2011 15:03:05 +0200 Subject: Get rid of update_details in favor of passing details to find_template. --- actionmailer/test/mailers/base_mailer.rb | 2 +- actionpack/lib/action_view/lookup_context.rb | 33 +++------------------- .../lib/action_view/renderer/abstract_renderer.rb | 16 ++++------- .../lib/action_view/renderer/partial_renderer.rb | 23 ++++++++------- .../lib/action_view/renderer/template_renderer.rb | 27 ++++++++---------- .../controller/new_base/render_partial_test.rb | 10 +++---- .../controller/new_base/render_template_test.rb | 6 ++-- actionpack/test/controller/render_test.rb | 4 ++- actionpack/test/template/lookup_context_test.rb | 10 ------- actionpack/test/template/render_test.rb | 5 ++++ 10 files changed, 50 insertions(+), 86 deletions(-) diff --git a/actionmailer/test/mailers/base_mailer.rb b/actionmailer/test/mailers/base_mailer.rb index 9416bc718e..e55d72fdb4 100644 --- a/actionmailer/test/mailers/base_mailer.rb +++ b/actionmailer/test/mailers/base_mailer.rb @@ -113,6 +113,6 @@ class BaseMailer < ActionMailer::Base end def email_with_translations - mail :body => render("email_with_translations.html") + mail :body => render("email_with_translations", :formats => [:html]) end end diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 96ef7da01b..8267977830 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -20,18 +20,16 @@ module ActionView def self.register_detail(name, options = {}, &block) self.registered_details << name - initialize = registered_details.map { |n| "self.#{n} = details[:#{n}]" } - update = registered_details.map { |n| "self.#{n} = details[:#{n}] if details.key?(:#{n})" } - Accessors.send :define_method, :"_#{name}_defaults", &block + Accessors.send :define_method, :"default_#{name}", &block Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1 def #{name} @details[:#{name}] end def #{name}=(value) - value = Array.wrap(value.presence || _#{name}_defaults) + value = Array.wrap(value.presence || default_#{name}) _set_detail(:#{name}, value) if value != @details[:#{name}] end @@ -39,11 +37,6 @@ module ActionView def initialize_details(details) #{initialize.join("\n")} end - - remove_possible_method :update_details - def update_details(details) - #{update.join("\n")} - end METHOD end @@ -88,24 +81,6 @@ module ActionView @cache = old_value end - # Update the details keys by merging the given hash into the current - # details hash. If a block is given, the details are modified just during - # the execution of the block and reverted to the previous value after. - def update_details(new_details) - if block_given? - old_details, old_key = @details.dup, @details_key - super - - begin - yield - ensure - @details, @details_key = old_details, old_key - end - else - super - end - end - protected def _set_detail(key, value) @@ -220,7 +195,7 @@ module ActionView # add :html as fallback to :js. def formats=(values) if values - values.concat(_formats_defaults) if values.delete "*/*" + values.concat(default_formats) if values.delete "*/*" values << :html if values == [:js] end super(values) @@ -246,7 +221,7 @@ module ActionView config.locale = value end - super(@skip_default_locale ? I18n.locale : _locale_defaults) + super(@skip_default_locale ? I18n.locale : default_locale) end # A method which only uses the first format in the formats array for layout lookup. diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb index 60c527beeb..24bae64ca5 100644 --- a/actionpack/lib/action_view/renderer/abstract_renderer.rb +++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb @@ -11,15 +11,13 @@ module ActionView raise NotImplementedError end - # Checks if the given path contains a format and if so, change - # the lookup context to take this new format into account. - def wrap_formats(value) - return yield unless value.is_a?(String) + protected - if value.sub!(formats_regexp, "") - update_details(:formats => [$1.to_sym]){ yield } - else - yield + def extract_format(value, details) + if value.is_a?(String) && value.sub!(formats_regexp, "") + ActiveSupport::Deprecation.warn "Passing the format in the template name is deprecated. " \ + "Please pass render with :formats => #{$1} instead.", caller + details[:formats] ||= [$1.to_sym] end end @@ -27,8 +25,6 @@ module ActionView @@formats_regexp ||= /\.(#{Mime::SET.symbols.join('|')})$/ end - protected - def instrument(name, options={}) ActiveSupport::Notifications.instrument("render_#{name}.action_view", options){ yield } end diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index cd0f7054a9..fc39ee8498 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -216,18 +216,15 @@ module ActionView def render(context, options, block) setup(context, options, block) + identifier = (@template = find_partial) ? @template.identifier : @path - wrap_formats(@path) do - identifier = ((@template = find_partial) ? @template.identifier : @path) - - if @collection - instrument(:collection, :identifier => identifier || "collection", :count => @collection.size) do - render_collection - end - else - instrument(:partial, :identifier => identifier) do - render_partial - end + if @collection + instrument(:collection, :identifier => identifier || "collection", :count => @collection.size) do + render_collection + end + else + instrument(:partial, :identifier => identifier) do + render_partial end end end @@ -271,6 +268,7 @@ module ActionView @options = options @locals = options[:locals] || {} @block = block + @details = options.slice(:formats, :locale, :handlers) if String === partial @object = options[:object] @@ -299,6 +297,7 @@ module ActionView "and is followed by any combinations of letters, numbers, or underscores.") end + extract_format(@path, @details) self end @@ -326,7 +325,7 @@ module ActionView def find_template(path=@path, locals=@locals.keys) prefixes = path.include?(?/) ? [] : @lookup_context.prefixes - @lookup_context.find_template(path, prefixes, true, locals) + @lookup_context.find_template(path, prefixes, true, locals, @details) end def collection_with_template diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb index 0a5b470a82..f3e7378f2b 100644 --- a/actionpack/lib/action_view/renderer/template_renderer.rb +++ b/actionpack/lib/action_view/renderer/template_renderer.rb @@ -4,30 +4,28 @@ require 'active_support/core_ext/array/wrap' module ActionView class TemplateRenderer < AbstractRenderer #:nodoc: def render(context, options) - @view = context - - wrap_formats(options[:template] || options[:file]) do - template = determine_template(options) - freeze_formats(template.formats, true) - render_template(template, options[:layout], options[:locals]) - end + @view = context + @details = options.slice(:formats, :locale, :handlers) + extract_format(options[:file] || options[:template], @details) + template = determine_template(options) + freeze_formats(template.formats, true) + render_template(template, options[:layout], options[:locals]) end # Determine the template to be rendered using the given options. def determine_template(options) #:nodoc: - keys = options[:locals].try(:keys) || [] - details = options.slice(:formats, :locale, :handlers) + keys = options[:locals].try(:keys) || [] if options.key?(:text) Template::Text.new(options[:text], formats.try(:first)) elsif options.key?(:file) - with_fallbacks { find_template(options[:file], nil, false, keys, details) } + with_fallbacks { find_template(options[:file], nil, false, keys, @details) } elsif options.key?(:inline) handler = Template.handler_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, :locals => keys) elsif options.key?(:template) options[:template].respond_to?(:render) ? - options[:template] : find_template(options[:template], options[:prefixes], false, keys) + options[:template] : find_template(options[:template], options[:prefixes], false, keys, @details) end end @@ -63,12 +61,11 @@ module ActionView begin with_layout_format do layout =~ /^\// ? - with_fallbacks { find_template(layout, nil, false, keys) } : find_template(layout, nil, false, keys) + with_fallbacks { find_template(layout, nil, false, keys, @details) } : find_template(layout, nil, false, keys, @details) end rescue ActionView::MissingTemplate - update_details(:formats => nil) do - raise unless template_exists?(layout) - end + all_details = @details.merge(:formats => @lookup_context.default_formats) + raise unless template_exists?(layout, nil, false, keys, all_details) end end end diff --git a/actionpack/test/controller/new_base/render_partial_test.rb b/actionpack/test/controller/new_base/render_partial_test.rb index 83b0d039ad..b4a25c49c9 100644 --- a/actionpack/test/controller/new_base/render_partial_test.rb +++ b/actionpack/test/controller/new_base/render_partial_test.rb @@ -7,12 +7,12 @@ module RenderPartial self.view_paths = [ActionView::FixtureResolver.new( "render_partial/basic/_basic.html.erb" => "BasicPartial!", "render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>", - "render_partial/basic/with_json.html.erb" => "<%= render 'with_json.json' %>", - "render_partial/basic/_with_json.json.erb" => "<%= render 'final' %>", + "render_partial/basic/with_json.html.erb" => "<%= render :partial => 'with_json', :formats => [:json] %>", + "render_partial/basic/_with_json.json.erb" => "<%= render :partial => 'final', :formats => [:json] %>", "render_partial/basic/_final.json.erb" => "{ final: json }", - "render_partial/basic/overriden.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'overriden' %><%= @test_unchanged %>", - "render_partial/basic/_overriden.html.erb" => "ParentPartial!", - "render_partial/child/_overriden.html.erb" => "OverridenPartial!" + "render_partial/basic/overriden.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'overriden' %><%= @test_unchanged %>", + "render_partial/basic/_overriden.html.erb" => "ParentPartial!", + "render_partial/child/_overriden.html.erb" => "OverridenPartial!" )] def html_with_json_inside_json diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb index 584f2d772c..ba804421da 100644 --- a/actionpack/test/controller/new_base/render_template_test.rb +++ b/actionpack/test/controller/new_base/render_template_test.rb @@ -10,8 +10,8 @@ module RenderTemplate "xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend", "with_raw.html.erb" => "Hello <%=raw 'this is raw' %>", "with_implicit_raw.html.erb" => "Hello <%== 'this is also raw' %>", - "test/with_json.html.erb" => "<%= render :template => 'test/with_json.json' %>", - "test/with_json.json.erb" => "<%= render :template => 'test/final' %>", + "test/with_json.html.erb" => "<%= render :template => 'test/with_json', :formats => [:json] %>", + "test/with_json.json.erb" => "<%= render :template => 'test/final', :formats => [:json] %>", "test/final.json.erb" => "{ final: json }", "test/with_error.html.erb" => "<%= idontexist %>" )] @@ -117,7 +117,7 @@ module RenderTemplate assert_response "{ final: json }" end - test "rendering a template with error properly exceprts the code" do + test "rendering a template with error properly excerts the code" do get :with_error assert_status 500 assert_match "undefined local variable or method `idontexist'", response.body diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index c46755417f..719e37799d 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -797,7 +797,9 @@ class RenderTest < ActionController::TestCase end def test_render_file - get :hello_world_file + assert_deprecated do + get :hello_world_file + end assert_equal "Hello world!", @response.body end diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb index 47b70f05ab..bac2530e3d 100644 --- a/actionpack/test/template/lookup_context_test.rb +++ b/actionpack/test/template/lookup_context_test.rb @@ -31,16 +31,6 @@ class LookupContextTest < ActiveSupport::TestCase assert @lookup_context.formats.frozen? end - test "allows me to change some details to execute an specific block of code" do - formats = Mime::SET - @lookup_context.update_details(:locale => :pt) do - assert_equal formats, @lookup_context.formats - assert_equal :pt, @lookup_context.locale - end - assert_equal formats, @lookup_context.formats - assert_equal :en, @lookup_context.locale - end - test "provides getters and setters for formats" do @lookup_context.formats = [:html] assert_equal [:html], @lookup_context.formats diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 525ef0d726..f3dce0b7f2 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -38,6 +38,11 @@ module RenderTestCases assert_equal "No Comment", @view.render(:file => "comments/empty", :formats => [:xml]) end + def test_render_template_with_format + assert_equal "

No Comment

", @view.render(:template => "comments/empty", :formats => [:html]) + assert_equal "No Comment", @view.render(:template => "comments/empty", :formats => [:xml]) + end + def test_render_file_with_localization old_locale, @view.locale = @view.locale, :da assert_equal "Hey verden", @view.render(:file => "test/hello_world") -- cgit v1.2.3 From c3fa2e9bf89039e90c45336979d17cb0c02a6cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 22 Sep 2011 15:06:04 +0200 Subject: Make handlers a registered detail. --- actionpack/lib/action_view/lookup_context.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 8267977830..ef1ef44317 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -44,8 +44,9 @@ module ActionView module Accessors #:nodoc: end - register_detail(:formats) { Mime::SET.symbols } register_detail(:locale) { [I18n.locale, I18n.default_locale] } + register_detail(:formats) { Mime::SET.symbols } + register_detail(:handlers){ Template::Handlers.extensions } class DetailsKey #:nodoc: alias :eql? :equal? @@ -159,10 +160,6 @@ module ActionView return name, prefixes end - def default_handlers #:nodoc: - @@default_handlers ||= Template::Handlers.extensions - end - def handlers_regexp #:nodoc: @@handlers_regexp ||= /\.(?:#{default_handlers.join('|')})$/ end @@ -173,7 +170,7 @@ module ActionView include ViewPaths def initialize(view_paths, details = {}, prefixes = []) - @details, @details_key = { :handlers => default_handlers }, nil + @details, @details_key = {}, nil @frozen_formats, @skip_default_locale = false, false @cache = true @prefixes = prefixes -- cgit v1.2.3 From 43d27e9105b385f64ec195f60d10ab3d64281bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 22 Sep 2011 15:37:38 +0200 Subject: Deprecate passing the template handler in the template name. For example, calling hello.erb is now deprecated. Since Rails 3.0 passing the handler had no effect whatsover. This commit simply deprecates such cases so we can clean up the code in later releases. --- .../action_dispatch/middleware/show_exceptions.rb | 4 +-- actionpack/lib/action_view/lookup_context.rb | 7 +++- .../lib/action_view/renderer/abstract_renderer.rb | 2 +- .../test/abstract/abstract_controller_test.rb | 6 ++-- actionpack/test/controller/caching_test.rb | 2 +- actionpack/test/controller/layout_test.rb | 4 +-- .../test/controller/new_base/render_file_test.rb | 10 +++--- actionpack/test/controller/render_test.rb | 28 +++++++-------- .../test/_layout_with_partial_and_yield.html.erb | 2 +- .../test/template/compiled_templates_test.rb | 16 ++++----- actionpack/test/template/log_subscriber_test.rb | 2 +- actionpack/test/template/render_test.rb | 42 +++++++++++----------- actionpack/test/template/streaming_render_test.rb | 16 ++++----- 13 files changed, 72 insertions(+), 69 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index a765c23dae..2fa68c64c5 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -86,8 +86,8 @@ module ActionDispatch :framework_trace => framework_trace(exception), :full_trace => full_trace(exception) ) - file = "rescues/#{@@rescue_templates[exception.class.name]}.erb" - body = template.render(:file => file, :layout => 'rescues/layout.erb') + file = "rescues/#{@@rescue_templates[exception.class.name]}" + body = template.render(:template => file, :layout => 'rescues/layout') render(status_code(exception), body) end diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index ef1ef44317..fa4bf70f77 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -147,7 +147,12 @@ module ActionView # as well as incorrectly putting part of the path in the template # name instead of the prefix. def normalize_name(name, prefixes) #:nodoc: - name = name.to_s.gsub(handlers_regexp, '') + name = name.to_s.sub(handlers_regexp) do |match| + ActiveSupport::Deprecation.warn "Passing a template handler in the template name is deprecated. " \ + "You can simply remove the handler name or pass render :handlers => [:#{match[1..-1]}] instead.", caller + "" + end + parts = name.split('/') name = parts.pop diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb index 24bae64ca5..1656cf7ec7 100644 --- a/actionpack/lib/action_view/renderer/abstract_renderer.rb +++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb @@ -16,7 +16,7 @@ module ActionView def extract_format(value, details) if value.is_a?(String) && value.sub!(formats_regexp, "") ActiveSupport::Deprecation.warn "Passing the format in the template name is deprecated. " \ - "Please pass render with :formats => #{$1} instead.", caller + "Please pass render with :formats => [:#{$1}] instead.", caller details[:formats] ||= [$1.to_sym] end end diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb index 5823e64637..bf068aedcd 100644 --- a/actionpack/test/abstract/abstract_controller_test.rb +++ b/actionpack/test/abstract/abstract_controller_test.rb @@ -50,7 +50,7 @@ module AbstractController end def index_to_string - self.response_body = render_to_string "index.erb" + self.response_body = render_to_string "index" end def action_with_ivars @@ -63,11 +63,11 @@ module AbstractController end def rendering_to_body - self.response_body = render_to_body :template => "naked_render.erb" + self.response_body = render_to_body :template => "naked_render" end def rendering_to_string - self.response_body = render_to_string :template => "naked_render.erb" + self.response_body = render_to_string :template => "naked_render" end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index da3314fe6d..f3b180283f 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -197,7 +197,7 @@ class ActionCachingTestController < CachingController caches_action :layout_false, :layout => false caches_action :record_not_found, :four_oh_four, :simple_runtime_error - layout 'talk_from_action.erb' + layout 'talk_from_action' def index @cache_this = MockTime.now.to_f.to_s diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index cafe2b9320..25299eb8b8 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -79,7 +79,7 @@ class DefaultLayoutController < LayoutTest end class AbsolutePathLayoutController < LayoutTest - layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/layouts/layout_test.erb') + layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/layouts/layout_test') end class HasOwnLayoutController < LayoutTest @@ -184,7 +184,7 @@ class RenderWithTemplateOptionController < LayoutTest end class SetsNonExistentLayoutFile < LayoutTest - layout "nofile.erb" + layout "nofile" end class LayoutExceptionRaised < ActionController::TestCase diff --git a/actionpack/test/controller/new_base/render_file_test.rb b/actionpack/test/controller/new_base/render_file_test.rb index 8b2fdf8f96..a961cbf849 100644 --- a/actionpack/test/controller/new_base/render_file_test.rb +++ b/actionpack/test/controller/new_base/render_file_test.rb @@ -10,7 +10,7 @@ module RenderFile def with_instance_variables @secret = 'in the sauce' - render :file => File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar.erb') + render :file => File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar') end def without_file_key @@ -19,7 +19,7 @@ module RenderFile def without_file_key_with_instance_variable @secret = 'in the sauce' - render File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar.erb') + render File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar') end def relative_path @@ -34,16 +34,16 @@ module RenderFile def pathname @secret = 'in the sauce' - render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. .. fixtures test dot.directory render_file_with_ivar.erb]) + render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. .. fixtures test dot.directory render_file_with_ivar]) end def with_locals - path = File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals.erb') + path = File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals') render :file => path, :locals => {:secret => 'in the sauce'} end def without_file_key_with_locals - path = FIXTURES.join('test/render_file_with_locals.erb').to_s + path = FIXTURES.join('test/render_file_with_locals').to_s render path, :locals => {:secret => 'in the sauce'} end end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 719e37799d..aea603b014 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -163,14 +163,14 @@ class TestController < ActionController::Base # :ported: def render_file_with_instance_variables @secret = 'in the sauce' - path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb') + path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar') render :file => path end # :ported: def render_file_as_string_with_instance_variables @secret = 'in the sauce' - path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')) + path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar')) render path end @@ -187,21 +187,21 @@ class TestController < ActionController::Base def render_file_using_pathname @secret = 'in the sauce' - render :file => Pathname.new(File.dirname(__FILE__)).join('..', 'fixtures', 'test', 'dot.directory', 'render_file_with_ivar.erb') + render :file => Pathname.new(File.dirname(__FILE__)).join('..', 'fixtures', 'test', 'dot.directory', 'render_file_with_ivar') end def render_file_from_template @secret = 'in the sauce' - @path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')) + @path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar')) end def render_file_with_locals - path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb') + path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals') render :file => path, :locals => {:secret => 'in the sauce'} end def render_file_as_string_with_locals - path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')) + path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals')) render path, :locals => {:secret => 'in the sauce'} end @@ -453,17 +453,13 @@ class TestController < ActionController::Base render :action => "potential_conflicts" end - # :deprecated: - # Tests being able to pick a .builder template over a .erb - # For instance, being able to have hello.xml.builder and hello.xml.erb - # and select one via "hello.builder" or "hello.erb" def hello_world_from_rxml_using_action - render :action => "hello_world_from_rxml.builder" + render :action => "hello_world_from_rxml", :handlers => [:builder] end # :deprecated: def hello_world_from_rxml_using_template - render :template => "test/hello_world_from_rxml.builder" + render :template => "test/hello_world_from_rxml", :handlers => [:builder] end def action_talk_to_layout @@ -525,8 +521,8 @@ class TestController < ActionController::Base render :action => "using_layout_around_block", :layout => "layouts/block_with_layout" end - def partial_dot_html - render :partial => 'partial.html.erb' + def partial_formats_html + render :partial => 'partial', :formats => [:html] end def partial @@ -1235,8 +1231,8 @@ class RenderTest < ActionController::TestCase assert_equal 'partial html', @response.body end - def test_should_render_html_partial_with_dot - get :partial_dot_html + def test_should_render_html_partial_with_formats + get :partial_formats_html assert_equal 'partial html', @response.body end diff --git a/actionpack/test/fixtures/test/_layout_with_partial_and_yield.html.erb b/actionpack/test/fixtures/test/_layout_with_partial_and_yield.html.erb index 5db0822f07..820e7db789 100644 --- a/actionpack/test/fixtures/test/_layout_with_partial_and_yield.html.erb +++ b/actionpack/test/fixtures/test/_layout_with_partial_and_yield.html.erb @@ -1,4 +1,4 @@ Before -<%= render :partial => "test/partial.html.erb" %> +<%= render :partial => "test/partial" %> <%= yield %> After diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb index 8be0f452fb..8fc78283d8 100644 --- a/actionpack/test/template/compiled_templates_test.rb +++ b/actionpack/test/template/compiled_templates_test.rb @@ -10,24 +10,24 @@ class CompiledTemplatesTest < Test::Unit::TestCase end def test_template_gets_recompiled_when_using_different_keys_in_local_assigns - assert_equal "one", render(:file => "test/render_file_with_locals_and_default.erb") - assert_equal "two", render(:file => "test/render_file_with_locals_and_default.erb", :locals => { :secret => "two" }) + assert_equal "one", render(:file => "test/render_file_with_locals_and_default") + assert_equal "two", render(:file => "test/render_file_with_locals_and_default", :locals => { :secret => "two" }) end def test_template_changes_are_not_reflected_with_cached_templates - assert_equal "Hello world!", render(:file => "test/hello_world.erb") + assert_equal "Hello world!", render(:file => "test/hello_world") modify_template "test/hello_world.erb", "Goodbye world!" do - assert_equal "Hello world!", render(:file => "test/hello_world.erb") + assert_equal "Hello world!", render(:file => "test/hello_world") end - assert_equal "Hello world!", render(:file => "test/hello_world.erb") + assert_equal "Hello world!", render(:file => "test/hello_world") end def test_template_changes_are_reflected_with_uncached_templates - assert_equal "Hello world!", render_without_cache(:file => "test/hello_world.erb") + assert_equal "Hello world!", render_without_cache(:file => "test/hello_world") modify_template "test/hello_world.erb", "Goodbye world!" do - assert_equal "Goodbye world!", render_without_cache(:file => "test/hello_world.erb") + assert_equal "Goodbye world!", render_without_cache(:file => "test/hello_world") end - assert_equal "Hello world!", render_without_cache(:file => "test/hello_world.erb") + assert_equal "Hello world!", render_without_cache(:file => "test/hello_world") end private diff --git a/actionpack/test/template/log_subscriber_test.rb b/actionpack/test/template/log_subscriber_test.rb index 50e1cccd3b..752b0f23a8 100644 --- a/actionpack/test/template/log_subscriber_test.rb +++ b/actionpack/test/template/log_subscriber_test.rb @@ -27,7 +27,7 @@ class AVLogSubscriberTest < ActiveSupport::TestCase end def test_render_file_template - @view.render(:file => "test/hello_world.erb") + @view.render(:file => "test/hello_world") wait assert_equal 1, @logger.logged(:info).size diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index f3dce0b7f2..120f91b0e7 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -21,11 +21,11 @@ module RenderTestCases end def test_render_file - assert_equal "Hello world!", @view.render(:file => "test/hello_world.erb") + assert_equal "Hello world!", @view.render(:file => "test/hello_world") end def test_render_file_not_using_full_path - assert_equal "Hello world!", @view.render(:file => "test/hello_world.erb") + assert_equal "Hello world!", @view.render(:file => "test/hello_world") end def test_render_file_without_specific_extension @@ -62,17 +62,17 @@ module RenderTestCases end def test_render_file_with_full_path - template_path = File.join(File.dirname(__FILE__), '../fixtures/test/hello_world.erb') + template_path = File.join(File.dirname(__FILE__), '../fixtures/test/hello_world') assert_equal "Hello world!", @view.render(:file => template_path) end def test_render_file_with_instance_variables - assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_ivar.erb") + assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_ivar") end def test_render_file_with_locals locals = { :secret => 'in the sauce' } - assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_locals.erb", :locals => locals) + assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_locals", :locals => locals) end def test_render_file_not_using_full_path_with_dot_in_path @@ -92,12 +92,12 @@ module RenderTestCases end def test_render_partial_at_top_level - # file fixtures/_top_level_partial_only.erb (not fixtures/test) + # file fixtures/_top_level_partial_only (not fixtures/test) assert_equal 'top level partial', @view.render(:partial => '/top_level_partial_only') end def test_render_partial_with_format_at_top_level - # file fixtures/_top_level_partial.html.erb (not fixtures/test, with format extension) + # file fixtures/_top_level_partial.html (not fixtures/test, with format extension) assert_equal 'top level partial html', @view.render(:partial => '/top_level_partial') end @@ -256,7 +256,7 @@ module RenderTestCases end def test_render_layout_with_block_and_other_partial_inside - render = @view.render(:layout => "test/layout_with_partial_and_yield.html.erb") { "Yield!" } + render = @view.render(:layout => "test/layout_with_partial_and_yield") { "Yield!" } assert_equal "Before\npartial html\nYield!\nAfter\n", render end @@ -293,24 +293,26 @@ module RenderTestCases end def test_render_ignores_templates_with_malformed_template_handlers - %w(malformed malformed.erb malformed.html.erb malformed.en.html.erb).each do |name| - assert_raise(ActionView::MissingTemplate) { @view.render(:file => "test/malformed/#{name}") } + ActiveSupport::Deprecation.silence do + %w(malformed malformed.erb malformed.html.erb malformed.en.html.erb).each do |name| + assert_raise(ActionView::MissingTemplate) { @view.render(:file => "test/malformed/#{name}") } + end end end def test_render_with_layout assert_equal %(\nHello world!\n), - @view.render(:file => "test/hello_world.erb", :layout => "layouts/yield") + @view.render(:file => "test/hello_world", :layout => "layouts/yield") end def test_render_with_layout_which_has_render_inline assert_equal %(welcome\nHello world!\n), - @view.render(:file => "test/hello_world.erb", :layout => "layouts/yield_with_render_inline_inside") + @view.render(:file => "test/hello_world", :layout => "layouts/yield_with_render_inline_inside") end def test_render_with_layout_which_renders_another_partial assert_equal %(partial html\nHello world!\n), - @view.render(:file => "test/hello_world.erb", :layout => "layouts/yield_with_render_partial_inside") + @view.render(:file => "test/hello_world", :layout => "layouts/yield_with_render_partial_inside") end def test_render_layout_with_block_and_yield @@ -355,17 +357,17 @@ module RenderTestCases def test_render_with_nested_layout assert_equal %(title\n\n
column
\n
content
\n), - @view.render(:file => "test/nested_layout.erb", :layout => "layouts/yield") + @view.render(:file => "test/nested_layout", :layout => "layouts/yield") end def test_render_with_file_in_layout assert_equal %(\ntitle\n\n), - @view.render(:file => "test/layout_render_file.erb") + @view.render(:file => "test/layout_render_file") end def test_render_layout_with_object assert_equal %(David), - @view.render(:file => "test/layout_render_object.erb") + @view.render(:file => "test/layout_render_object") end end @@ -403,7 +405,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase if '1.9'.respond_to?(:force_encoding) def test_render_utf8_template_with_magic_comment with_external_encoding Encoding::ASCII_8BIT do - result = @view.render(:file => "test/utf8_magic.html.erb", :layouts => "layouts/yield") + result = @view.render(:file => "test/utf8_magic.html", :layouts => "layouts/yield") assert_equal Encoding::UTF_8, result.encoding assert_equal "\nРусский \nтекст\n\nUTF-8\nUTF-8\nUTF-8\n", result end @@ -411,7 +413,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase def test_render_utf8_template_with_default_external_encoding with_external_encoding Encoding::UTF_8 do - result = @view.render(:file => "test/utf8.html.erb", :layouts => "layouts/yield") + result = @view.render(:file => "test/utf8.html", :layouts => "layouts/yield") assert_equal Encoding::UTF_8, result.encoding assert_equal "Русский текст\n\nUTF-8\nUTF-8\nUTF-8\n", result end @@ -420,7 +422,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase def test_render_utf8_template_with_incompatible_external_encoding with_external_encoding Encoding::SHIFT_JIS do begin - @view.render(:file => "test/utf8.html.erb", :layouts => "layouts/yield") + @view.render(:file => "test/utf8.html", :layouts => "layouts/yield") flunk 'Should have raised incompatible encoding error' rescue ActionView::Template::Error => error assert_match 'Your template was not saved as valid Shift_JIS', error.original_exception.message @@ -431,7 +433,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase def test_render_utf8_template_with_partial_with_incompatible_encoding with_external_encoding Encoding::SHIFT_JIS do begin - @view.render(:file => "test/utf8_magic_with_bare_partial.html.erb", :layouts => "layouts/yield") + @view.render(:file => "test/utf8_magic_with_bare_partial.html", :layouts => "layouts/yield") flunk 'Should have raised incompatible encoding error' rescue ActionView::Template::Error => error assert_match 'Your template was not saved as valid Shift_JIS', error.original_exception.message diff --git a/actionpack/test/template/streaming_render_test.rb b/actionpack/test/template/streaming_render_test.rb index 023ce723ed..4d01352b43 100644 --- a/actionpack/test/template/streaming_render_test.rb +++ b/actionpack/test/template/streaming_render_test.rb @@ -28,7 +28,7 @@ class FiberedTest < ActiveSupport::TestCase def test_streaming_works content = [] - body = render_body(:template => "test/hello_world.erb", :layout => "layouts/yield") + body = render_body(:template => "test/hello_world", :layout => "layouts/yield") body.each do |piece| content << piece @@ -42,12 +42,12 @@ class FiberedTest < ActiveSupport::TestCase end def test_render_file - assert_equal "Hello world!", buffered_render(:file => "test/hello_world.erb") + assert_equal "Hello world!", buffered_render(:file => "test/hello_world") end def test_render_file_with_locals locals = { :secret => 'in the sauce' } - assert_equal "The secret is in the sauce\n", buffered_render(:file => "test/render_file_with_locals.erb", :locals => locals) + assert_equal "The secret is in the sauce\n", buffered_render(:file => "test/render_file_with_locals", :locals => locals) end def test_render_partial @@ -64,27 +64,27 @@ class FiberedTest < ActiveSupport::TestCase def test_render_with_layout assert_equal %(\nHello world!\n), - buffered_render(:template => "test/hello_world.erb", :layout => "layouts/yield") + buffered_render(:template => "test/hello_world", :layout => "layouts/yield") end def test_render_with_layout_which_has_render_inline assert_equal %(welcome\nHello world!\n), - buffered_render(:template => "test/hello_world.erb", :layout => "layouts/yield_with_render_inline_inside") + buffered_render(:template => "test/hello_world", :layout => "layouts/yield_with_render_inline_inside") end def test_render_with_layout_which_renders_another_partial assert_equal %(partial html\nHello world!\n), - buffered_render(:template => "test/hello_world.erb", :layout => "layouts/yield_with_render_partial_inside") + buffered_render(:template => "test/hello_world", :layout => "layouts/yield_with_render_partial_inside") end def test_render_with_nested_layout assert_equal %(title\n\n
column
\n
content
\n), - buffered_render(:template => "test/nested_layout.erb", :layout => "layouts/yield") + buffered_render(:template => "test/nested_layout", :layout => "layouts/yield") end def test_render_with_file_in_layout assert_equal %(\ntitle\n\n), - buffered_render(:template => "test/layout_render_file.erb") + buffered_render(:template => "test/layout_render_file") end def test_render_with_handler_without_streaming_support -- cgit v1.2.3 From 667ef57de641f4915f50d93f35756892151ee34b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 22 Sep 2011 14:14:24 -0300 Subject: No need to create a range object --- activesupport/lib/active_support/cache/file_store.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index ab2382d98c..3f516d4808 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -130,13 +130,13 @@ module ActiveSupport hash, dir_1 = hash.divmod(0x1000) dir_2 = hash.modulo(0x1000) fname_paths = [] - + # Make sure file name doesn't exceed file system limits. begin - fname_paths << fname[0...FILENAME_MAX_SIZE] + fname_paths << fname[0, FILENAME_MAX_SIZE] fname = fname[FILENAME_MAX_SIZE..-1] end until fname.blank? - + File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, *fname_paths) end -- cgit v1.2.3 From c070cc4ab41fd848fc72f19e7f99d75b1e1fd097 Mon Sep 17 00:00:00 2001 From: docunext Date: Wed, 21 Sep 2011 13:19:48 -0400 Subject: Fixes #1489 again, with updated code and numerous tests to confirm --- actionpack/lib/sprockets/helpers/rails_helper.rb | 2 +- actionpack/test/template/sprockets_helper_test.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb index 457ab93ae3..c569124c94 100644 --- a/actionpack/lib/sprockets/helpers/rails_helper.rb +++ b/actionpack/lib/sprockets/helpers/rails_helper.rb @@ -57,7 +57,7 @@ module Sprockets def asset_path(source, options = {}) source = source.logical_path if source.respond_to?(:logical_path) - path = asset_paths.compute_public_path(source, 'assets', options.merge(:body => true)) + path = asset_paths.compute_public_path(source, asset_prefix, options.merge(:body => true)) options[:body] ? "#{path}?body=1" : path end diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index c0fb07a29b..a44a16750f 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -47,6 +47,16 @@ class SprocketsHelperTest < ActionView::TestCase asset_path("logo.png", :digest => false) end + test "custom_asset_path" do + @config.assets.prefix = '/s' + assert_match %r{/s/logo-[0-9a-f]+.png}, + asset_path("logo.png") + assert_match %r{/s/logo-[0-9a-f]+.png}, + asset_path("logo.png", :digest => true) + assert_match %r{/s/logo.png}, + asset_path("logo.png", :digest => false) + end + test "asset_path with root relative assets" do assert_equal "/images/logo", asset_path("/images/logo") -- cgit v1.2.3 From 1de89e5e077e2e0948e78af500e78db4daaa03cc Mon Sep 17 00:00:00 2001 From: Terence Lee Date: Thu, 22 Sep 2011 12:29:46 -0500 Subject: AR wants sqlite3 1.3.4 --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 508d083fe6..a1585e279c 100644 --- a/Gemfile +++ b/Gemfile @@ -63,7 +63,7 @@ platforms :ruby do gem "nokogiri", ">= 1.4.5" # AR - gem "sqlite3", "~> 1.3.3" + gem "sqlite3", "~> 1.3.4" group :db do gem "pg", ">= 0.11.0" unless ENV['TRAVIS'] # once pg is on travis this can be removed -- cgit v1.2.3 From 9d46823b5d00e78c6ffaaae731a9a7acf6bb2b14 Mon Sep 17 00:00:00 2001 From: Terence Lee Date: Thu, 22 Sep 2011 12:03:59 -0500 Subject: set env to let rails know we're precompiling --- actionpack/lib/sprockets/assets.rake | 3 +++ railties/test/application/assets_test.rb | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake index e38ac6b489..7241671db0 100644 --- a/actionpack/lib/sprockets/assets.rake +++ b/actionpack/lib/sprockets/assets.rake @@ -1,6 +1,9 @@ namespace :assets do desc "Compile all the assets named in config.assets.precompile" task :precompile do + # let rails know we're precompiling assets + ENV["RAILS_ASSETS_PRECOMPILE"] = 'true' + # We need to do this dance because RAILS_GROUPS is used # too early in the boot process and changing here is already too late. if ENV["RAILS_GROUPS"].to_s.empty? || ENV["RAILS_ENV"].to_s.empty? diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index a62ef1e70e..c4a24f0f73 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -102,6 +102,15 @@ module ApplicationTests assert !File.exists?("#{app_path}/public/assets/something.min.css") end + test "precompile sets flag notifying rails its precompiling" do + compile = < Date: Thu, 22 Sep 2011 14:05:25 -0700 Subject: fixed a bug with the json serialization when the class setting is set to not include the root, but an instance is serialized with the root option passed as true --- activemodel/lib/active_model/serializers/json.rb | 22 ++++++++++------------ .../cases/serializers/json_serialization_test.rb | 10 ++++++++++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/activemodel/lib/active_model/serializers/json.rb b/activemodel/lib/active_model/serializers/json.rb index 4fbccd7419..3c713311fd 100644 --- a/activemodel/lib/active_model/serializers/json.rb +++ b/activemodel/lib/active_model/serializers/json.rb @@ -88,19 +88,17 @@ module ActiveModel # "title": "So I was thinking"}]} def as_json(options = nil) - hash = serializable_hash(options) - - include_root = include_root_in_json - if options.try(:key?, :root) - include_root = options[:root] - end - - if include_root - custom_root = options && options[:root] - hash = { custom_root || self.class.model_name.element => hash } + opts_root = options[:root] if options.try(:key?, :root) + if opts_root + custom_root = opts_root == true ? self.class.model_name.element : opts_root + { custom_root => serializable_hash(options) } + elsif opts_root == false + serializable_hash(options) + elsif include_root_in_json + { self.class.model_name.element => serializable_hash(options) } + else + serializable_hash(options) end - - hash end def from_json(json, include_root=include_root_in_json) diff --git a/activemodel/test/cases/serializers/json_serialization_test.rb b/activemodel/test/cases/serializers/json_serialization_test.rb index 5e1e7d897a..40fdcf20ca 100644 --- a/activemodel/test/cases/serializers/json_serialization_test.rb +++ b/activemodel/test/cases/serializers/json_serialization_test.rb @@ -56,6 +56,16 @@ class JsonSerializationTest < ActiveModel::TestCase end end + test "should include root in json (option) even if the default is set to false" do + begin + Contact.include_root_in_json = false + json = @contact.to_json(:root => true) + assert_match %r{^\{"contact":\{}, json + ensure + Contact.include_root_in_json = true + end + end + test "should not include root in json (option)" do json = @contact.to_json(:root => false) -- cgit v1.2.3 From 4bfbdc133a37c6046b8854d3659ba75597d1d37e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 23 Sep 2011 00:19:46 +0200 Subject: Refactor AMo as_json. --- activemodel/lib/active_model/serializers/json.rb | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/activemodel/lib/active_model/serializers/json.rb b/activemodel/lib/active_model/serializers/json.rb index 3c713311fd..885964633f 100644 --- a/activemodel/lib/active_model/serializers/json.rb +++ b/activemodel/lib/active_model/serializers/json.rb @@ -86,16 +86,12 @@ module ActiveModel # "title": "Welcome to the weblog"}, # {"comments": [{"body": "Don't think too hard"}], # "title": "So I was thinking"}]} - def as_json(options = nil) - opts_root = options[:root] if options.try(:key?, :root) - if opts_root - custom_root = opts_root == true ? self.class.model_name.element : opts_root - { custom_root => serializable_hash(options) } - elsif opts_root == false - serializable_hash(options) - elsif include_root_in_json - { self.class.model_name.element => serializable_hash(options) } + root = include_root_in_json + root = options[:root] if options.try(:key?, :root) + if root + root = self.class.model_name.element if root == true + { root => serializable_hash(options) } else serializable_hash(options) end -- cgit v1.2.3 From f8e6664d8647acf11c8f98e00ec5a23326be5d19 Mon Sep 17 00:00:00 2001 From: Nick Sutterer Date: Thu, 22 Sep 2011 16:02:14 +0200 Subject: added tests for render :file/:template and the :formats/:handlers/:locale options. --- actionpack/test/fixtures/comments/empty.de.html.erb | 1 + actionpack/test/fixtures/comments/empty.html.builder | 1 + actionpack/test/template/render_test.rb | 18 +++++++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 actionpack/test/fixtures/comments/empty.de.html.erb create mode 100644 actionpack/test/fixtures/comments/empty.html.builder diff --git a/actionpack/test/fixtures/comments/empty.de.html.erb b/actionpack/test/fixtures/comments/empty.de.html.erb new file mode 100644 index 0000000000..cffd90dd26 --- /dev/null +++ b/actionpack/test/fixtures/comments/empty.de.html.erb @@ -0,0 +1 @@ +

Kein Kommentar

\ No newline at end of file diff --git a/actionpack/test/fixtures/comments/empty.html.builder b/actionpack/test/fixtures/comments/empty.html.builder new file mode 100644 index 0000000000..2b0c7207a3 --- /dev/null +++ b/actionpack/test/fixtures/comments/empty.html.builder @@ -0,0 +1 @@ +xml.h1 'No Comment' \ No newline at end of file diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 120f91b0e7..634e1cdd9f 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -42,8 +42,24 @@ module RenderTestCases assert_equal "

No Comment

", @view.render(:template => "comments/empty", :formats => [:html]) assert_equal "No Comment", @view.render(:template => "comments/empty", :formats => [:xml]) end + + def test_render_file_with_locale + assert_equal "

Kein Kommentar

", @view.render(:file => "comments/empty", :locale => [:de]) + end + + def test_render_template_with_locale + assert_equal "

Kein Kommentar

", @view.render(:template => "comments/empty", :locale => [:de]) + end + + def test_render_file_with_handlers + assert_equal "

No Comment

\n", @view.render(:file => "comments/empty", :handlers => [:builder]) + end + + def test_render_template_with_handlers + assert_equal "

No Comment

\n", @view.render(:template => "comments/empty", :handlers => [:builder]) + end - def test_render_file_with_localization + def test_render_file_with_localization_on_context_level old_locale, @view.locale = @view.locale, :da assert_equal "Hey verden", @view.render(:file => "test/hello_world") ensure -- cgit v1.2.3 From 2e3eb2560b7686a633d6de35c4cd9131504aee38 Mon Sep 17 00:00:00 2001 From: Nick Sutterer Date: Thu, 22 Sep 2011 23:51:44 +0200 Subject: Allow both sym and array for details options in #render. using LC#registered_details to extract options. --- actionpack/lib/action_view/renderer/abstract_renderer.rb | 13 ++++++++++++- actionpack/lib/action_view/renderer/template_renderer.rb | 2 +- actionpack/test/template/render_test.rb | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb index 1656cf7ec7..03feeff16c 100644 --- a/actionpack/lib/action_view/renderer/abstract_renderer.rb +++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb @@ -12,7 +12,18 @@ module ActionView end protected - + + def extract_details(options) + details = {} + @lookup_context.registered_details.each do |key| + next unless value = options[key] + details[key] = Array.wrap(value) + end + details + end + + + def extract_format(value, details) if value.is_a?(String) && value.sub!(formats_regexp, "") ActiveSupport::Deprecation.warn "Passing the format in the template name is deprecated. " \ diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb index f3e7378f2b..ac91d333ba 100644 --- a/actionpack/lib/action_view/renderer/template_renderer.rb +++ b/actionpack/lib/action_view/renderer/template_renderer.rb @@ -5,7 +5,7 @@ module ActionView class TemplateRenderer < AbstractRenderer #:nodoc: def render(context, options) @view = context - @details = options.slice(:formats, :locale, :handlers) + @details = extract_details(options) extract_format(options[:file] || options[:template], @details) template = determine_template(options) freeze_formats(template.formats, true) diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 634e1cdd9f..5637f3f42e 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -36,6 +36,7 @@ module RenderTestCases def test_render_file_with_format assert_equal "

No Comment

", @view.render(:file => "comments/empty", :formats => [:html]) assert_equal "No Comment", @view.render(:file => "comments/empty", :formats => [:xml]) + assert_equal "No Comment", @view.render(:file => "comments/empty", :formats => :xml) end def test_render_template_with_format @@ -45,6 +46,7 @@ module RenderTestCases def test_render_file_with_locale assert_equal "

Kein Kommentar

", @view.render(:file => "comments/empty", :locale => [:de]) + assert_equal "

Kein Kommentar

", @view.render(:file => "comments/empty", :locale => :de) end def test_render_template_with_locale @@ -53,6 +55,7 @@ module RenderTestCases def test_render_file_with_handlers assert_equal "

No Comment

\n", @view.render(:file => "comments/empty", :handlers => [:builder]) + assert_equal "

No Comment

\n", @view.render(:file => "comments/empty", :handlers => :builder) end def test_render_template_with_handlers -- cgit v1.2.3 From 552df29cc849500b6e2cbc4186e23c330909ae8e Mon Sep 17 00:00:00 2001 From: Nick Sutterer Date: Fri, 23 Sep 2011 00:03:48 +0200 Subject: Using #extract_details in PartialRenderer, too! --- actionpack/lib/action_view/renderer/abstract_renderer.rb | 2 -- actionpack/lib/action_view/renderer/partial_renderer.rb | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb index 03feeff16c..c0936441ac 100644 --- a/actionpack/lib/action_view/renderer/abstract_renderer.rb +++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb @@ -22,8 +22,6 @@ module ActionView details end - - def extract_format(value, details) if value.is_a?(String) && value.sub!(formats_regexp, "") ActiveSupport::Deprecation.warn "Passing the format in the template name is deprecated. " \ diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index fc39ee8498..e808fa3415 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -268,7 +268,7 @@ module ActionView @options = options @locals = options[:locals] || {} @block = block - @details = options.slice(:formats, :locale, :handlers) + @details = extract_details(options) if String === partial @object = options[:object] -- cgit v1.2.3 From 48d27363f2d6f20a7178dc9bd0d664bc4e60212d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 23 Sep 2011 00:42:20 +0200 Subject: Fix failing tests and add tests for :formats on partial. --- actionpack/test/template/render_test.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 5637f3f42e..0ef3239f83 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -34,14 +34,14 @@ module RenderTestCases # Test if :formats, :locale etc. options are passed correctly to the resolvers. def test_render_file_with_format - assert_equal "

No Comment

", @view.render(:file => "comments/empty", :formats => [:html]) - assert_equal "No Comment", @view.render(:file => "comments/empty", :formats => [:xml]) - assert_equal "No Comment", @view.render(:file => "comments/empty", :formats => :xml) + assert_match "

No Comment

", @view.render(:file => "comments/empty", :formats => [:html]) + assert_match "No Comment", @view.render(:file => "comments/empty", :formats => [:xml]) + assert_match "No Comment", @view.render(:file => "comments/empty", :formats => :xml) end def test_render_template_with_format - assert_equal "

No Comment

", @view.render(:template => "comments/empty", :formats => [:html]) - assert_equal "No Comment", @view.render(:template => "comments/empty", :formats => [:xml]) + assert_match "

No Comment

", @view.render(:template => "comments/empty", :formats => [:html]) + assert_match "No Comment", @view.render(:template => "comments/empty", :formats => [:xml]) end def test_render_file_with_locale @@ -110,6 +110,11 @@ module RenderTestCases assert_equal 'partial html', @view.render(:partial => 'test/partial') end + def test_render_partial_with_selected_format + assert_equal 'partial html', @view.render(:partial => 'test/partial', :formats => :html) + assert_equal 'partial js', @view.render(:partial => 'test/partial', :formats => [:js]) + end + def test_render_partial_at_top_level # file fixtures/_top_level_partial_only (not fixtures/test) assert_equal 'top level partial', @view.render(:partial => '/top_level_partial_only') -- cgit v1.2.3 From d62fc8e0211ca2657899f061888d1756a3c257dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 23 Sep 2011 00:44:55 +0200 Subject: Update CHANGELOG. --- actionpack/CHANGELOG | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 5ee14dbdf1..c3ff677529 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,13 @@ *Rails 3.2.0 (unreleased)* +* Passing formats or handlers to render :template and friends is deprecated. For example: [Nick Sutterer & José Valim] + + render :template => "foo.html.erb" + + Instead, you can provide :handlers and :formats directly as option: + + render :template => "foo", :formats => [:html, :js], :handlers => :erb + * Changed log level of warning for missing CSRF token from :debug to :warn. [Mike Dillon] * content_tag_for and div_for can now take the collection of records. It will also yield the record as the first argument if you set a receiving argument in your block [Prem Sichanugrist] -- cgit v1.2.3 From 17ba60a724aad508327bf52212335420f4d81364 Mon Sep 17 00:00:00 2001 From: Waynn Lue Date: Fri, 23 Sep 2011 00:25:37 -0700 Subject: pluralize "locales" since that's what's used in other parts of the document, and add a missing "on" --- railties/guides/source/i18n.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 45a069b0a3..2d4cc13571 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -8,7 +8,7 @@ So, in the process of _internationalizing_ your Rails application you have to: * Ensure you have support for i18n * Tell Rails where to find locale dictionaries -* Tell Rails how to set, preserve and switch locale +* Tell Rails how to set, preserve and switch locales In the process of _localizing_ your application you'll probably want to do the following three things: @@ -16,7 +16,7 @@ In the process of _localizing_ your application you'll probably want to do the f * Abstract strings in your application into keyed dictionaries -- e.g. flash messages, static text in your views, etc. * Store the resulting dictionaries somewhere -This guide will walk you through the I18n API and contains a tutorial how to internationalize a Rails application from the start. +This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start. endprologue. -- cgit v1.2.3 From 310565f537b5eeb134e9a4bb0801358432f03e04 Mon Sep 17 00:00:00 2001 From: Ryan Oblak Date: Thu, 22 Sep 2011 12:17:42 -0700 Subject: Added ActiveSupport::Inflector.safe_constantize and String#safe_constantize; refactored common constantize tests into ConstantizeTestCases --- .../active_support/core_ext/string/inflections.rb | 19 ++++++++++--- .../lib/active_support/inflector/methods.rb | 27 +++++++++++++++++++ activesupport/test/constantize_test_cases.rb | 31 ++++++++++++++++++++++ activesupport/test/core_ext/string_ext_test.rb | 23 +++++++++++++++- activesupport/test/inflector_test.rb | 27 +++++++------------ 5 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 activesupport/test/constantize_test_cases.rb diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index 002688d6c0..b4218cb42c 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -33,14 +33,27 @@ class String # +constantize+ tries to find a declared constant with the name specified # in the string. It raises a NameError when the name is not in CamelCase - # or is not initialized. + # or is not initialized. See ActiveSupport::Inflector.constantize # # Examples - # "Module".constantize # => Module - # "Class".constantize # => Class + # "Module".constantize # => Module + # "Class".constantize # => Class + # "blargle".safe_constantize # => NameError: wrong constant name blargle def constantize ActiveSupport::Inflector.constantize(self) end + + # +safe_constantize+ tries to find a declared constant with the name specified + # in the string. It returns nil when the name is not in CamelCase + # or is not initialized. See ActiveSupport::Inflector.safe_constantize + # + # Examples + # "Module".safe_constantize # => Module + # "Class".safe_constantize # => Class + # "blargle".safe_constantize # => nil + def safe_constantize + ActiveSupport::Inflector.safe_constantize(self) + end # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize # is set to :lower then camelize produces lowerCamelCase. diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 423b5abd20..b22e39c7c2 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -224,6 +224,33 @@ module ActiveSupport end end + # Tries to find a constant with the name specified in the argument string: + # + # "Module".safe_constantize # => Module + # "Test::Unit".safe_constantize # => Test::Unit + # + # The name is assumed to be the one of a top-level constant, no matter whether + # it starts with "::" or not. No lexical context is taken into account: + # + # C = 'outside' + # module M + # C = 'inside' + # C # => 'inside' + # "C".safe_constantize # => 'outside', same as ::C + # end + # + # nil is returned when the name is not in CamelCase or the constant is + # unknown. + # + # "blargle".safe_constantize # => nil + def safe_constantize(camel_cased_word) + begin + camel_cased_word.constantize + rescue NameError + nil + end + end + # Turns a number into an ordinal string used to denote the position in an # ordered sequence such as 1st, 2nd, 3rd, 4th. # diff --git a/activesupport/test/constantize_test_cases.rb b/activesupport/test/constantize_test_cases.rb new file mode 100644 index 0000000000..b8a866b6c9 --- /dev/null +++ b/activesupport/test/constantize_test_cases.rb @@ -0,0 +1,31 @@ +module Ace + module Base + class Case + end + end +end + +module ConstantizeTestCases + def run_constantize_tests_on + assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } + assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } + assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } + assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } + assert_raise(NameError) { yield("UnknownClass") } + assert_raise(NameError) { yield("An invalid string") } + assert_raise(NameError) { yield("InvalidClass\n") } + assert_raise(NameError) { yield("Ace::Base::ConstantizeTestCases") } + end + + def run_safe_constantize_tests_on + assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } + assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } + assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } + assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } + assert_nothing_raised { assert_equal nil, yield("UnknownClass") } + assert_nothing_raised { assert_equal nil, yield("An invalid string") } + assert_nothing_raised { assert_equal nil, yield("InvalidClass\n") } + assert_nothing_raised { assert_equal nil, yield("blargle") } + assert_nothing_raised { assert_equal nil, yield("Ace::Base::ConstantizeTestCases") } + end +end \ No newline at end of file diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 81a284dded..5c1dddaf96 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -2,6 +2,7 @@ require 'date' require 'abstract_unit' require 'inflector_test_cases' +require 'constantize_test_cases' require 'active_support/inflector' require 'active_support/core_ext/string' @@ -9,9 +10,17 @@ require 'active_support/time' require 'active_support/core_ext/string/strip' require 'active_support/core_ext/string/output_safety' +module Ace + module Base + class Case + end + end +end + class StringInflectionsTest < Test::Unit::TestCase include InflectorTestCases - + include ConstantizeTestCases + def test_erb_escape string = [192, 60].pack('CC') expected = 192.chr + "<" @@ -292,6 +301,18 @@ class StringInflectionsTest < Test::Unit::TestCase "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8').truncate(10) end end + + def test_constantize + run_constantize_tests_on do |string| + string.constantize + end + end + + def test_safe_constantize + run_safe_constantize_tests_on do |string| + string.safe_constantize + end + end end class StringBehaviourTest < Test::Unit::TestCase diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index b9e299af75..5c956e0075 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -2,16 +2,11 @@ require 'abstract_unit' require 'active_support/inflector' require 'inflector_test_cases' - -module Ace - module Base - class Case - end - end -end +require 'constantize_test_cases' class InflectorTest < Test::Unit::TestCase include InflectorTestCases + include ConstantizeTestCases def test_pluralize_plurals assert_equal "plurals", ActiveSupport::Inflector.pluralize("plurals") @@ -282,17 +277,15 @@ class InflectorTest < Test::Unit::TestCase end def test_constantize - assert_nothing_raised { assert_equal Ace::Base::Case, ActiveSupport::Inflector.constantize("Ace::Base::Case") } - assert_nothing_raised { assert_equal Ace::Base::Case, ActiveSupport::Inflector.constantize("::Ace::Base::Case") } - assert_nothing_raised { assert_equal InflectorTest, ActiveSupport::Inflector.constantize("InflectorTest") } - assert_nothing_raised { assert_equal InflectorTest, ActiveSupport::Inflector.constantize("::InflectorTest") } - assert_raise(NameError) { ActiveSupport::Inflector.constantize("UnknownClass") } - assert_raise(NameError) { ActiveSupport::Inflector.constantize("An invalid string") } - assert_raise(NameError) { ActiveSupport::Inflector.constantize("InvalidClass\n") } + run_constantize_tests_on do |string| + ActiveSupport::Inflector.constantize(string) + end end - - def test_constantize_does_lexical_lookup - assert_raise(NameError) { ActiveSupport::Inflector.constantize("Ace::Base::InflectorTest") } + + def test_safe_constantize + run_safe_constantize_tests_on do |string| + ActiveSupport::Inflector.safe_constantize(string) + end end def test_ordinal -- cgit v1.2.3 From b2f34d1e3591df0f19f01ba30160661175c9a6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 23 Sep 2011 16:16:53 +0200 Subject: Ensure that constantize just rescues NameError that applies to the constant being currently loaded. --- .../lib/active_support/inflector/methods.rb | 24 ++++++++++++++++++---- activesupport/test/constantize_test_cases.rb | 6 ++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index b22e39c7c2..dd232a5e2f 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -245,12 +245,15 @@ module ActiveSupport # "blargle".safe_constantize # => nil def safe_constantize(camel_cased_word) begin - camel_cased_word.constantize - rescue NameError - nil + constantize(camel_cased_word) + rescue NameError => e + raise unless e.message =~ /uninitialized constant #{const_regexp(camel_cased_word)}$/ || + e.name.to_s == camel_cased_word.to_s + rescue ArgumentError => e + raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/ end end - + # Turns a number into an ordinal string used to denote the position in an # ordered sequence such as 1st, 2nd, 3rd, 4th. # @@ -273,5 +276,18 @@ module ActiveSupport end end end + + private + + # Mount a regular expression that will match part by part of the constant. + # For instance, Foo::Bar::Baz will generate Foo(::Bar(::Baz)?)? + def const_regexp(camel_cased_word) #:nodoc: + parts = camel_cased_word.split("::") + last = parts.pop + + parts.reverse.inject(last) do |acc, part| + part.empty? ? acc : "#{part}(::#{acc})?" + end + end end end diff --git a/activesupport/test/constantize_test_cases.rb b/activesupport/test/constantize_test_cases.rb index b8a866b6c9..81d200a0c8 100644 --- a/activesupport/test/constantize_test_cases.rb +++ b/activesupport/test/constantize_test_cases.rb @@ -12,8 +12,11 @@ module ConstantizeTestCases assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } assert_raise(NameError) { yield("UnknownClass") } + assert_raise(NameError) { yield("UnknownClass::Ace") } + assert_raise(NameError) { yield("UnknownClass::Ace::Base") } assert_raise(NameError) { yield("An invalid string") } assert_raise(NameError) { yield("InvalidClass\n") } + assert_raise(NameError) { yield("Ace::ConstantizeTestCases") } assert_raise(NameError) { yield("Ace::Base::ConstantizeTestCases") } end @@ -23,9 +26,12 @@ module ConstantizeTestCases assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } assert_nothing_raised { assert_equal nil, yield("UnknownClass") } + assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace") } + assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace::Base") } assert_nothing_raised { assert_equal nil, yield("An invalid string") } assert_nothing_raised { assert_equal nil, yield("InvalidClass\n") } assert_nothing_raised { assert_equal nil, yield("blargle") } + assert_nothing_raised { assert_equal nil, yield("Ace::ConstantizeTestCases") } assert_nothing_raised { assert_equal nil, yield("Ace::Base::ConstantizeTestCases") } end end \ No newline at end of file -- cgit v1.2.3 From e8987c30d0dc3ae5903a6d3a6e293641759b6fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 23 Sep 2011 16:46:33 +0200 Subject: Use safe_constantize where possible. --- actionpack/lib/action_controller/metal/params_wrapper.rb | 9 +++------ actionpack/lib/action_view/test_case.rb | 4 +--- activesupport/lib/active_support/core_ext/module/reachable.rb | 4 +--- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/actionpack/lib/action_controller/metal/params_wrapper.rb b/actionpack/lib/action_controller/metal/params_wrapper.rb index 6acbb23907..e0d8e1c992 100644 --- a/actionpack/lib/action_controller/metal/params_wrapper.rb +++ b/actionpack/lib/action_controller/metal/params_wrapper.rb @@ -141,19 +141,16 @@ module ActionController # try to find Foo::Bar::User, Foo::User and finally User. def _default_wrap_model #:nodoc: return nil if self.anonymous? - model_name = self.name.sub(/Controller$/, '').singularize begin - model_klass = model_name.constantize - rescue NameError, ArgumentError => e - if e.message =~ /is not missing constant|uninitialized constant #{model_name}/ + if model_klass = model_name.safe_constantize + model_klass + else namespaces = model_name.split("::") namespaces.delete_at(-2) break if namespaces.last == model_name model_name = namespaces.join("::") - else - raise end end until model_klass diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 2cc85a9f69..c4d51d7946 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -54,10 +54,8 @@ module ActionView end def determine_default_helper_class(name) - mod = name.sub(/Test$/, '').constantize + mod = name.sub(/Test$/, '').safe_constantize mod.is_a?(Class) ? nil : mod - rescue NameError - nil end def helper_method(*methods) diff --git a/activesupport/lib/active_support/core_ext/module/reachable.rb b/activesupport/lib/active_support/core_ext/module/reachable.rb index 443d2c3d53..5d3d0e9851 100644 --- a/activesupport/lib/active_support/core_ext/module/reachable.rb +++ b/activesupport/lib/active_support/core_ext/module/reachable.rb @@ -3,8 +3,6 @@ require 'active_support/core_ext/string/inflections' class Module def reachable? #:nodoc: - !anonymous? && name.constantize.equal?(self) - rescue NameError - false + !anonymous? && name.safe_constantize.equal?(self) end end -- cgit v1.2.3 From 36699977f2ddbb937aac97998d2d8503499c57e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 23 Sep 2011 16:49:05 +0200 Subject: Update CHANGELOG for safe_constantize. --- activesupport/CHANGELOG | 2 ++ activesupport/lib/active_support/inflector/methods.rb | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 537980d6a1..63f406cd9f 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.2.0 (unreleased)* +* Added safe_constantize that constantizes a string but returns nil instead of an exception if the constant (or part of it) does not exist [Ryan Oblak] + * ActiveSupport::OrderedHash is now marked as extractable when using Array#extract_options! [Prem Sichanugrist] * Added Array#prepend as an alias for Array#unshift and Array#append as an alias for Array#<< [DHH] diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index dd232a5e2f..934529d496 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -239,10 +239,13 @@ module ActiveSupport # "C".safe_constantize # => 'outside', same as ::C # end # - # nil is returned when the name is not in CamelCase or the constant is + # nil is returned when the name is not in CamelCase or the constant (or part of it) is # unknown. # # "blargle".safe_constantize # => nil + # "UnknownModule".safe_constantize # => nil + # "UnknownModule::Foo::Bar".safe_constantize # => nil + # def safe_constantize(camel_cased_word) begin constantize(camel_cased_word) -- cgit v1.2.3 From 06634f44d0fd106a49d4f7a63bcb1532006e3742 Mon Sep 17 00:00:00 2001 From: Ryan Oblak Date: Fri, 23 Sep 2011 10:21:34 -0700 Subject: Minor doc fix to String#constantize --- activesupport/lib/active_support/core_ext/string/inflections.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index b4218cb42c..c7ceeb9de4 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -36,9 +36,9 @@ class String # or is not initialized. See ActiveSupport::Inflector.constantize # # Examples - # "Module".constantize # => Module - # "Class".constantize # => Class - # "blargle".safe_constantize # => NameError: wrong constant name blargle + # "Module".constantize # => Module + # "Class".constantize # => Class + # "blargle".constantize # => NameError: wrong constant name blargle def constantize ActiveSupport::Inflector.constantize(self) end -- cgit v1.2.3 From a29c2bfba3cfdfcbb19f809105861b6ca81e72cc Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Fri, 23 Sep 2011 13:34:11 -0500 Subject: Remove Sprockets compute_public_path, AV compute_public_path can be used directly --- actionpack/lib/sprockets/helpers/rails_helper.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb index c569124c94..fe822b338e 100644 --- a/actionpack/lib/sprockets/helpers/rails_helper.rb +++ b/actionpack/lib/sprockets/helpers/rails_helper.rb @@ -13,7 +13,6 @@ module Sprockets controller = self.controller if respond_to?(:controller) paths = RailsHelper::AssetPaths.new(config, controller) paths.asset_environment = asset_environment - paths.asset_prefix = asset_prefix paths.asset_digests = asset_digests paths.compile_assets = compile_assets? paths.digest_assets = digest_assets? @@ -102,10 +101,6 @@ module Sprockets class AssetNotPrecompiledError < StandardError; end - def compute_public_path(source, dir, options = {}) - super(source, asset_prefix, options) - end - # Return the filesystem path for the source def compute_source_path(source, ext) asset_for(source, ext) -- cgit v1.2.3 From eb367afeed2905d1036f46940aa6c91323f7faab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 24 Sep 2011 01:56:49 +0200 Subject: `rake assets:precompile` loads the application but does not initialize it. To the app developer, this means configuration add in config/initializers/* will not be executed. Plugins developers need to special case their initializers that are meant to be run in the assets group by adding :group => :assets. Conflicts: railties/CHANGELOG railties/test/application/assets_test.rb --- actionpack/lib/sprockets/assets.rake | 3 +- actionpack/lib/sprockets/bootstrap.rb | 65 ++++++++++++++++ actionpack/lib/sprockets/railtie.rb | 59 +-------------- railties/CHANGELOG | 12 +++ railties/lib/rails/application.rb | 5 +- railties/lib/rails/application/bootstrap.rb | 16 ++-- railties/lib/rails/engine.rb | 4 +- railties/lib/rails/initializable.rb | 8 +- railties/test/application/assets_test.rb | 110 ++++++++++++++++++---------- railties/test/initializable_test.rb | 2 +- railties/test/isolation/abstract_unit.rb | 9 +++ 11 files changed, 183 insertions(+), 110 deletions(-) create mode 100644 actionpack/lib/sprockets/bootstrap.rb diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake index 7241671db0..5dd48fea98 100644 --- a/actionpack/lib/sprockets/assets.rake +++ b/actionpack/lib/sprockets/assets.rake @@ -11,8 +11,9 @@ namespace :assets do ENV["RAILS_ENV"] ||= "production" Kernel.exec $0, *ARGV else - Rake::Task["environment"].invoke Rake::Task["tmp:cache:clear"].invoke + Rails.application.initialize!(:assets) + Sprockets::Bootstrap.new(Rails.application).run # Ensure that action view is loaded and the appropriate sprockets hooks get executed ActionView::Base diff --git a/actionpack/lib/sprockets/bootstrap.rb b/actionpack/lib/sprockets/bootstrap.rb new file mode 100644 index 0000000000..ed1ed09374 --- /dev/null +++ b/actionpack/lib/sprockets/bootstrap.rb @@ -0,0 +1,65 @@ +module Sprockets + class Bootstrap + def initialize(app) + @app = app + end + + # TODO: Get rid of config.assets.enabled + def run + app, config = @app, @app.config + return unless app.assets + + config.assets.paths.each { |path| app.assets.append_path(path) } + + if config.assets.compress + # temporarily hardcode default JS compressor to uglify. Soon, it will work + # the same as SCSS, where a default plugin sets the default. + unless config.assets.js_compressor == false + app.assets.js_compressor = LazyCompressor.new { expand_js_compressor(config.assets.js_compressor || :uglifier) } + end + + unless config.assets.css_compressor == false + app.assets.css_compressor = LazyCompressor.new { expand_css_compressor(config.assets.css_compressor) } + end + end + + if config.assets.compile + app.routes.prepend do + mount app.assets => config.assets.prefix + end + end + + if config.assets.digest + app.assets = app.assets.index + end + end + + protected + + def expand_js_compressor(sym) + case sym + when :closure + require 'closure-compiler' + Closure::Compiler.new + when :uglifier + require 'uglifier' + Uglifier.new + when :yui + require 'yui/compressor' + YUI::JavaScriptCompressor.new + else + sym + end + end + + def expand_css_compressor(sym) + case sym + when :yui + require 'yui/compressor' + YUI::CssCompressor.new + else + sym + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index 9b31604dbe..edcd4c1113 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -1,5 +1,6 @@ module Sprockets - autoload :Helpers, "sprockets/helpers" + autoload :Bootstrap, "sprockets/bootstrap" + autoload :Helpers, "sprockets/helpers" autoload :LazyCompressor, "sprockets/compressors" autoload :NullCompressor, "sprockets/compressors" autoload :StaticCompiler, "sprockets/static_compiler" @@ -12,7 +13,7 @@ module Sprockets load "sprockets/assets.rake" end - initializer "sprockets.environment" do |app| + initializer "sprockets.environment", :group => :assets do |app| config = app.config next unless config.assets.enabled @@ -51,59 +52,7 @@ module Sprockets # are compiled, and so that other Railties have an opportunity to # register compressors. config.after_initialize do |app| - next unless app.assets - config = app.config - - config.assets.paths.each { |path| app.assets.append_path(path) } - - if config.assets.compress - # temporarily hardcode default JS compressor to uglify. Soon, it will work - # the same as SCSS, where a default plugin sets the default. - unless config.assets.js_compressor == false - app.assets.js_compressor = LazyCompressor.new { expand_js_compressor(config.assets.js_compressor || :uglifier) } - end - - unless config.assets.css_compressor == false - app.assets.css_compressor = LazyCompressor.new { expand_css_compressor(config.assets.css_compressor) } - end - end - - if config.assets.compile - app.routes.prepend do - mount app.assets => config.assets.prefix - end - end - - if config.assets.digest - app.assets = app.assets.index - end + Sprockets::Bootstrap.new(app).run end - - protected - def expand_js_compressor(sym) - case sym - when :closure - require 'closure-compiler' - Closure::Compiler.new - when :uglifier - require 'uglifier' - Uglifier.new - when :yui - require 'yui/compressor' - YUI::JavaScriptCompressor.new - else - sym - end - end - - def expand_css_compressor(sym) - case sym - when :yui - require 'yui/compressor' - YUI::CssCompressor.new - else - sym - end - end end end diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 72e5921d6d..54eef0473c 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -10,6 +10,18 @@ * Removed old 'config.paths.app.controller' API in favor of 'config.paths["app/controller"]' API. [Guillermo Iguaran] + +*Rails 3.1.1 + +* `rake assets:precompile` loads the application but does not initialize it. + + To the app developer, this means configuration add in + config/initializers/* will not be executed. + + Plugins developers need to special case their initializers that are + meant to be run in the assets group by adding :group => :assets. + + *Rails 3.1.0 (August 30, 2011)* * The default database schema file is written as UTF-8. [Aaron Patterson] diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 528c96ef3e..90d7d27af1 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -83,7 +83,6 @@ module Rails require environment if environment end - def reload_routes! routes_reloader.reload! end @@ -92,9 +91,9 @@ module Rails @routes_reloader ||= RoutesReloader.new end - def initialize! + def initialize!(group=nil) raise "Application has been already initialized." if @initialized - run_initializers(self) + run_initializers(group, self) @initialized = true self end diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index c9b147d075..0aff05b681 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -7,21 +7,21 @@ module Rails module Bootstrap include Initializable - initializer :load_environment_hook do end + initializer :load_environment_hook, :group => :all do end - initializer :load_active_support do + initializer :load_active_support, :group => :all do require "active_support/all" unless config.active_support.bare end # Preload all frameworks specified by the Configuration#frameworks. # Used by Passenger to ensure everything's loaded before forking and # to avoid autoload race conditions in JRuby. - initializer :preload_frameworks do + initializer :preload_frameworks, :group => :all do ActiveSupport::Autoload.eager_autoload! if config.preload_frameworks end # Initialize the logger early in the stack in case we need to log some deprecation. - initializer :initialize_logger do + initializer :initialize_logger, :group => :all do Rails.logger ||= config.logger || begin path = config.paths["log"].first logger = ActiveSupport::BufferedLogger.new(path) @@ -41,7 +41,7 @@ module Rails end # Initialize cache early in the stack so railties can make use of it. - initializer :initialize_cache do + initializer :initialize_cache, :group => :all do unless defined?(RAILS_CACHE) silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(config.cache_store) } @@ -51,7 +51,7 @@ module Rails end end - initializer :set_clear_dependencies_hook do + initializer :set_clear_dependencies_hook, :group => :all do ActionDispatch::Reloader.to_cleanup do ActiveSupport::DescendantsTracker.clear ActiveSupport::Dependencies.clear @@ -60,11 +60,11 @@ module Rails # Sets the dependency loading mechanism. # TODO: Remove files from the $" and always use require. - initializer :initialize_dependency_mechanism do + initializer :initialize_dependency_mechanism, :group => :all do ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load end - initializer :bootstrap_hook do |app| + initializer :bootstrap_hook, :group => :all do |app| ActiveSupport.run_load_hooks(:before_initialize, app) end end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 89b151beb6..0e1e719596 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -537,12 +537,12 @@ module Rails end end - initializer :load_environment_config, :before => :load_environment_hook do + initializer :load_environment_config, :before => :load_environment_hook, :group => :all do environment = paths["config/environments"].existent.first require environment if environment end - initializer :append_assets_path do |app| + initializer :append_assets_path, :group => :assets do |app| app.config.assets.paths.unshift(*paths["vendor/assets"].existent_directories) app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories) app.config.assets.paths.unshift(*paths["app/assets"].existent_directories) diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb index 686a2dc0cb..4c1da0a5a5 100644 --- a/railties/lib/rails/initializable.rb +++ b/railties/lib/rails/initializable.rb @@ -21,6 +21,10 @@ module Rails @options[:after] end + def belongs_to?(group) + @options[:group] == group || @options[:group] == :all + end + def run(*args) @context.instance_exec(*args, &block) end @@ -44,10 +48,10 @@ module Rails end end - def run_initializers(*args) + def run_initializers(group=nil, *args) return if instance_variable_defined?(:@ran) initializers.tsort.each do |initializer| - initializer.run(*args) + initializer.run(*args) if group.nil? || initializer.belongs_to?(group) end @ran = true end diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index c4a24f0f73..fb570d8f47 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -21,6 +21,12 @@ module ApplicationTests @app ||= Rails.application end + def precompile! + capture(:stdout) do + Dir.chdir(app_path){ `bundle exec rake assets:precompile` } + end + end + test "assets routes have higher priority" do app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();" @@ -38,7 +44,7 @@ module ApplicationTests test "assets do not require compressors until it is used" do app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();" - app_file "config/initializers/compile.rb", "Rails.application.config.assets.compile = true" + add_to_env_config "production", "config.assets.compile = true" ENV["RAILS_ENV"] = "production" require "#{app_path}/config/environment" @@ -54,9 +60,8 @@ module ApplicationTests app_file "app/assets/javascripts/foo/application.js", "alert();" ENV["RAILS_ENV"] = nil - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! + files = Dir["#{app_path}/public/assets/application-*.js"] files << Dir["#{app_path}/public/assets/foo/application-*.js"].first files.each do |file| @@ -80,13 +85,12 @@ module ApplicationTests "happy.happy.face.png", "happy", "happy.face", "-happyface", "-happy.png", "-happy.face.png", "_happyface", "_happy.face.png", "_happy.png"] + images_should_compile.each do |filename| app_file "app/assets/images/#{filename}", "happy" end - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! images_should_compile.each do |filename| assert File.exists?("#{app_path}/public/assets/#{filename}") @@ -103,11 +107,12 @@ module ApplicationTests end test "precompile sets flag notifying rails its precompiling" do - compile = < :assets do + raise "ENV RAILS_ASSETS_PRECOMPILE not set" unless ENV["RAILS_ASSETS_PRECOMPILE"] + end + RUBY + precompile! assert $?.success? end @@ -127,9 +132,7 @@ COMPILE # digest is default in false, we must enable it for test environment add_to_config "config.assets.digest = true" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! manifest = "#{app_path}/public/assets/manifest.yml" @@ -146,9 +149,7 @@ COMPILE add_to_config "config.assets.manifest = '#{app_path}/shared'" FileUtils.mkdir "#{app_path}/shared" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! manifest = "#{app_path}/shared/manifest.yml" @@ -164,9 +165,7 @@ COMPILE add_to_config "config.assets.digest = true" add_to_config "config.assets.prefix = '/x'" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! manifest = "#{app_path}/public/x/manifest.yml" assets = YAML.load_file(manifest) @@ -178,9 +177,7 @@ COMPILE app_file "app/assets/javascripts/application.js", "alert();" add_to_config "config.assets.digest = false" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! assert File.exists?("#{app_path}/public/assets/application.js") assert File.exists?("#{app_path}/public/assets/application.css") @@ -194,12 +191,11 @@ COMPILE test "assets do not require any assets group gem when manifest file is present" do app_file "app/assets/javascripts/application.js", "alert();" - app_file "config/initializers/serve_static_assets.rb", "Rails.application.config.serve_static_assets = true" + add_to_env_config "production", "config.serve_static_assets = true" ENV["RAILS_ENV"] = "production" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! + manifest = "#{app_path}/public/assets/manifest.yml" assets = YAML.load_file(manifest) asset_path = assets["application.js"] @@ -223,9 +219,7 @@ COMPILE RUBY ENV["RAILS_ENV"] = "production" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! # Create file after of precompile app_file "app/assets/javascripts/app.js", "alert();" @@ -249,9 +243,7 @@ COMPILE RUBY ENV["RAILS_ENV"] = "development" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end + precompile! # Create file after of precompile app_file "app/assets/javascripts/app.js", "alert();" @@ -292,10 +284,7 @@ COMPILE app_file "app/assets/images/レイルズ.png", "not a image really" add_to_config "config.assets.precompile = [ /\.png$$/, /application.(css|js)$/ ]" - capture(:stdout) do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } - end - + precompile! assert File.exists?("#{app_path}/public/assets/レイルズ.png") manifest = "#{app_path}/public/assets/manifest.yml" @@ -367,5 +356,50 @@ COMPILE assert_match "alert();", last_response.body assert_equal 200, last_response.status end + + test "assets are concatenated when debug is off and compile is off either if debug_assets param is provided" do + app_with_assets_in_view + + # config.assets.debug and config.assets.compile are false for production environment + ENV["RAILS_ENV"] = "production" + precompile! + + require "#{app_path}/config/environment" + + class ::PostsController < ActionController::Base ; end + + # the debug_assets params isn't used if compile is off + get '/posts?debug_assets=true' + assert_match(/ - - + + + The +body+ param is required by Sprockets. h4. Turning Debugging off -You can turn off debug mode by updating +development.rb+ to include: +You can turn off debug mode by updating +config/environments/development.rb+ to include: - + config.assets.debug = false - +
-When debug mode is off Sprockets will concatenate and run the necessary preprocessors on all files, generating the following HTML: +When debug mode is off Sprockets concatenates and runs the necessary preprocessors on all files. With debug mode turned off the manifest above would generate instead: - + -Assets are compiled and cached on the first request after the server is started. Sprockets sets a +must-revalidate+ Cache-Control HTTP header to reduce request overhead on subsequent requests -- on these the browser gets a 304 (not-modified) response. +Assets are compiled and cached on the first request after the server is started. Sprockets sets a +must-revalidate+ Cache-Control HTTP header to reduce request overhead on subsequent requests -- on these the browser gets a 304 (Not Modified) response. If any of the files in the manifest have changed between requests, the server responds with a new compiled file. -You can put +?debug_assets=true+ or +?debug_assets=1+ at the end of a URL to enable debug mode on-demand, and this will render individual tags for each file. This is useful for tracking down exact line numbers when debugging. - -Debug can also be set in the Rails helper methods: +Debug mode can also be enabled in the Rails helper methods: <%= stylesheet_link_tag "application", :debug => true %> <%= javascript_include_tag "application", :debug => true %> -The +:debug+ option is ignored if the debug mode is off. +The +:debug+ option is redundant if debug mode is on. You could potentially also enable compression in development mode as a sanity check, and disable it on-demand as required for debugging. - h3. In Production In the production environment Rails uses the fingerprinting scheme outlined above. By default it is assumed that assets have been precompiled and will be served as static assets by your web server. -- cgit v1.2.3 From 41365a8275dcb6d2e2fbe21ae2b2dfc52db19c1f Mon Sep 17 00:00:00 2001 From: Colin Shield & Ian Lesperance Date: Wed, 28 Sep 2011 15:23:47 -0700 Subject: Fixed digest authentication for requests with a query string [#3158] --- activeresource/lib/active_resource/connection.rb | 5 ++++- activeresource/test/cases/authorization_test.rb | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb index d923204dde..592fca96a4 100644 --- a/activeresource/lib/active_resource/connection.rb +++ b/activeresource/lib/active_resource/connection.rb @@ -238,8 +238,11 @@ module ActiveResource def digest_auth_header(http_method, uri) params = extract_params_from_response + request_uri = uri.path + request_uri << "?#{uri.query}" if uri.query + ha1 = Digest::MD5.hexdigest("#{@user}:#{params['realm']}:#{@password}") - ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{uri.path}") + ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{request_uri}") params.merge!('cnonce' => client_nonce) request_digest = Digest::MD5.hexdigest([ha1, params['nonce'], "0", params['cnonce'], params['qop'], ha2].join(":")) diff --git a/activeresource/test/cases/authorization_test.rb b/activeresource/test/cases/authorization_test.rb index 69ef9a2821..17cd9b30fc 100644 --- a/activeresource/test/cases/authorization_test.rb +++ b/activeresource/test/cases/authorization_test.rb @@ -131,6 +131,12 @@ class AuthorizationTest < Test::Unit::TestCase assert_equal blank_digest_auth_header("/people/2.json", "fad396f6a34aeba28e28b9b96ddbb671"), authorization_header['Authorization'] end + def test_authorization_header_with_query_string_if_auth_type_is_digest + @authenticated_conn.auth_type = :digest + authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.json?only=name')) + assert_equal blank_digest_auth_header("/people/2.json?only=name", "f8457b0b5d21b6b80737a386217afb24"), authorization_header['Authorization'] + end + def test_get david = decode(@authenticated_conn.get("/people/2.json")) assert_equal "David", david["name"] -- cgit v1.2.3 From 64b0c8888b908ede5372e0a70cb4cb8731d372ba Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 28 Sep 2011 20:13:24 -0300 Subject: javascript_path and stylesheet_path should honor the asset pipelining --- actionpack/lib/sprockets/helpers/rails_helper.rb | 10 ++++++++++ actionpack/test/template/sprockets_helper_test.rb | 20 ++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb index c8c6c3ddd9..e1d8fccf04 100644 --- a/actionpack/lib/sprockets/helpers/rails_helper.rb +++ b/actionpack/lib/sprockets/helpers/rails_helper.rb @@ -65,6 +65,16 @@ module Sprockets end alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route + def javascript_path(source) + asset_path(source) + end + alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with an javascript_path named route + + def stylesheet_path(source) + asset_path(source) + end + alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with an stylesheet_path named route + private def debug_assets? compile_assets? && (Rails.application.config.assets.debug || params[:debug_assets]) diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index b1e6db7b34..fd3e01ec03 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -134,6 +134,22 @@ class SprocketsHelperTest < ActionView::TestCase path_to_image("logo.png") end + test "javascript_path" do + assert_match %r{/assets/application-[0-9a-f]+.js}, + javascript_path("application.js") + + assert_match %r{/assets/application-[0-9a-f]+.js}, + path_to_javascript("application.js") + end + + test "stylesheet_path" do + assert_match %r{/assets/application-[0-9a-f]+.css}, + stylesheet_path("application.css") + + assert_match %r{/assets/application-[0-9a-f]+.css}, + path_to_stylesheet("application.css") + end + test "stylesheets served without a controller in do not use asset hosts when the default protocol is :request" do @controller = nil @config.action_controller.asset_host = "assets-%d.example.com" @@ -157,7 +173,7 @@ class SprocketsHelperTest < ActionView::TestCase asset_path("/images/logo.gif") end - test "javascript path" do + test "javascript path through asset_path" do assert_match %r{/assets/application-[0-9a-f]+.js}, asset_path(:application, :ext => "js") @@ -202,7 +218,7 @@ class SprocketsHelperTest < ActionView::TestCase javascript_include_tag(:application) end - test "stylesheet path" do + test "stylesheet path through asset_path" do assert_match %r{/assets/application-[0-9a-f]+.css}, asset_path(:application, :ext => "css") assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", :ext => "css") -- cgit v1.2.3 From 148e4a541361f140f13aa35bb43b3d57c95831d6 Mon Sep 17 00:00:00 2001 From: Dmitriy Kiriyenko Date: Thu, 29 Sep 2011 15:35:25 +0300 Subject: Honour RAILS_ENV environment variable when running rake. --- railties/lib/rails/generators/actions.rb | 2 +- railties/test/generators/actions_test.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 575f4bb106..5af5d3b856 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -252,7 +252,7 @@ module Rails # def rake(command, options={}) log :rake, command - env = options[:env] || 'development' + env = options[:env] || ENV["RAILS_ENV"] || 'development' sudo = options[:sudo] && RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ ? 'sudo ' : '' in_root { run("#{sudo}#{extify(:rake)} #{command} RAILS_ENV=#{env}", :verbose => false) } end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 94e9abb3cc..e621f7f6f7 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -189,6 +189,22 @@ class ActionsTest < Rails::Generators::TestCase action :rake, 'log:clear', :env => 'production' end + def test_rake_with_rails_env_variable_should_run_rake_command_in_env + generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', :verbose => false) + old_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "production" + action :rake, 'log:clear' + ensure + ENV["RAILS_ENV"] = old_env + end + + def test_env_option_should_win_over_rails_env_variable_when_running_rake + generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', :verbose => false) + old_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "staging" + action :rake, 'log:clear', :env => 'production' + ensure + ENV["RAILS_ENV"] = old_env + end + def test_rake_with_sudo_option_should_run_rake_command_with_sudo generator.expects(:run).once.with('sudo rake log:clear RAILS_ENV=development', :verbose => false) action :rake, 'log:clear', :sudo => true -- cgit v1.2.3 From adb8ac153f8e9e497eaecf62165c0bd53c18149a Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 29 Sep 2011 17:59:40 +0100 Subject: Don't call self.class unless necessary. Closes #3171. --- activerecord/lib/active_record/reflection.rb | 4 ++-- activerecord/test/cases/reflection_test.rb | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 1929a808ed..120ff0cac6 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -212,8 +212,8 @@ module ActiveRecord end # klass option is necessary to support loading polymorphic associations - def association_primary_key(klass = self.klass) - options[:primary_key] || klass.primary_key + def association_primary_key(klass = nil) + options[:primary_key] || (klass || self.klass).primary_key end def active_record_primary_key diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 0a48f418b1..ca9d88fbd5 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -244,6 +244,7 @@ class ReflectionTest < ActiveRecord::TestCase # Normal association assert_equal "id", Author.reflect_on_association(:posts).association_primary_key.to_s assert_equal "name", Author.reflect_on_association(:essay).association_primary_key.to_s + assert_equal "name", Essay.reflect_on_association(:writer).association_primary_key.to_s # Through association (uses the :primary_key option from the source reflection) assert_equal "nick", Author.reflect_on_association(:subscribers).association_primary_key.to_s -- cgit v1.2.3 From d2888de5985c7018a5be23d44143ec3c6cef9032 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 29 Sep 2011 16:07:59 -0300 Subject: Add CHANGELOG entries --- actionpack/CHANGELOG | 40 ++++++++++++++++++++++++++++++++++++++++ activerecord/CHANGELOG | 26 +++++++++++++++++++++++++- railties/CHANGELOG | 2 ++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index c3ff677529..e8c619723f 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -56,6 +56,46 @@ *Rails 3.1.1 (unreleased)* +* javascript_path and stylesheet_path now refer to /assets if asset pipelining +is on. [Santiago Pastorino] + +* button_to support form option. Now you're able to pass for example +'data-type' => 'json'. [ihower] + +* image_path and image_tag should use /assets if asset pipelining is turned +on. Closes #3126 [Santiago Pastorino and christos] + +* Avoid use of existing precompiled assets during rake assets:precompile run. +Closes #3119 [Guillermo Iguaran] + +* Copy assets to nondigested filenames too [Santiago Pastorino] + +* Give precedence to `config.digest = false` over the existence of +manifest.yml asset digests [christos] + +* escape options for the stylesheet_link_tag method [Alexey Vakhov] + +* Re-launch assets:precompile task using (Rake.)ruby instead of Kernel.exec so +it works on Windows [cablegram] + +* env var passed to process shouldn't be modified in process method. [Santiago +Pastorino] + +* `rake assets:precompile` loads the application but does not initialize +it. + + To the app developer, this means configuration add in + config/initializers/* will not be executed. + + Plugins developers need to special case their initializers that are + meant to be run in the assets group by adding :group => :assets. [José Valim] + +* Sprockets uses config.assets.prefix for asset_path [asee] + +* FileStore key_file_path properly limit filenames to 255 characters. [phuibonhoa] + +* Fix Hash#to_query edge case with html_safe strings. [brainopia] + * Allow asset tag helper methods to accept :digest => false option in order to completely avoid the digest generation. Useful for linking assets from static html files or from emails when the user could probably look at an older html email with an older asset. [Santiago Pastorino] diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index a54526dd41..f974b5d237 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,4 +1,28 @@ -Wed Sep 7 15:25:02 2011 Aaron Patterson +*Rails 3.1.1 (unreleased)* + +* Add deprecation for the preload_associations method. Fixes #3022. + + [Jon Leighton] + +* Don't require a DB connection when loading a model that uses set_primary_key. GH #2807. + + [Jon Leighton] + +* Fix using select() with a habtm association, e.g. Person.friends.select(:name). GH #3030 and + #2923. + + [Hendy Tanata] + +* Fix belongs_to polymorphic with custom primary key on target. GH #3104. + + [Jon Leighton] + +* CollectionProxy#replace should change the DB records rather than just mutating the array. + Fixes #3020. + + [Jon Leighton] + +* LRU cache in mysql and sqlite are now per-process caches. * lib/active_record/connection_adapters/mysql_adapter.rb: LRU cache keys are per process id. diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 54eef0473c..992519ee92 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -13,6 +13,8 @@ *Rails 3.1.1 +* Add jquery-rails to Gemfile of plugins, test/dummy app needs it. Closes #3091. [Santiago Pastorino] + * `rake assets:precompile` loads the application but does not initialize it. To the app developer, this means configuration add in -- cgit v1.2.3 From da914fa35c014b7753e609e25c6a45d3cda11274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Hock=20Isaza?= Date: Thu, 29 Sep 2011 20:07:19 -0500 Subject: Fixing `as_json` method for ActiveRecord models. When you've got an AR Model and you override the `as_json` method, you should be able to add default options to the renderer, like this: class User < ActiveRecord::Base def as_json(options = {}) super(options.merge(:except => [:password_digest])) end end This was not possible before this commit. See the added test case. --- activemodel/test/cases/serializers/json_serialization_test.rb | 10 ++++++++++ activesupport/lib/active_support/core_ext/object/to_json.rb | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/activemodel/test/cases/serializers/json_serialization_test.rb b/activemodel/test/cases/serializers/json_serialization_test.rb index 40fdcf20ca..a754d610b9 100644 --- a/activemodel/test/cases/serializers/json_serialization_test.rb +++ b/activemodel/test/cases/serializers/json_serialization_test.rb @@ -206,4 +206,14 @@ class JsonSerializationTest < ActiveModel::TestCase assert_no_match %r{"preferences":}, json end + test "custom as_json options should be extendible" do + def @contact.as_json(options = {}); super(options.merge(:only => [:name])); end + json = @contact.to_json + + assert_match %r{"name":"Konata Izumi"}, json + assert_no_match %r{"created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}}, json + assert_no_match %r{"awesome":}, json + assert_no_match %r{"preferences":}, json + end + end diff --git a/activesupport/lib/active_support/core_ext/object/to_json.rb b/activesupport/lib/active_support/core_ext/object/to_json.rb index 14ef27340e..82e232070d 100644 --- a/activesupport/lib/active_support/core_ext/object/to_json.rb +++ b/activesupport/lib/active_support/core_ext/object/to_json.rb @@ -12,7 +12,7 @@ end [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass| klass.class_eval <<-RUBY, __FILE__, __LINE__ # Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info. - def to_json(options = nil) + def to_json(options = {}) ActiveSupport::JSON.encode(self, options) end RUBY -- cgit v1.2.3 From e81c427fe8a5bba8e5c8dd4b2a57c5e20b1c5fd0 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Fri, 30 Sep 2011 14:12:43 +0530 Subject: possibly useless use of :: in void context Warning removed --- railties/test/application/configuration_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 448982f9de..97ad47ac14 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -306,7 +306,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors") end @@ -319,7 +319,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailInterceptor, ::MyOtherMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors") end @@ -332,7 +332,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers") end @@ -345,7 +345,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailObserver, ::MyOtherMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers") end -- cgit v1.2.3 From b0b436ebcea8206015b3f52bb5915a7bba7cc5a9 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Fri, 30 Sep 2011 15:56:38 +0530 Subject: warning removed : '&' interpreted as argument prefix --- railties/lib/rails/generators/actions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 5af5d3b856..b26839644e 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -90,7 +90,7 @@ module Rails append_file "Gemfile", "\ngroup #{name} do\n", :force => true @in_group = true - instance_eval &block + instance_eval(&block) @in_group = false append_file "Gemfile", "end\n", :force => true -- cgit v1.2.3 From 37b9594a8e08916e1e9ae9a6aaffc13ef516ad11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 30 Sep 2011 12:45:36 +0200 Subject: Set the default options value for as_json in the encoder object. --- activesupport/lib/active_support/core_ext/object/to_json.rb | 2 +- activesupport/lib/active_support/json/encoding.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/object/to_json.rb b/activesupport/lib/active_support/core_ext/object/to_json.rb index 82e232070d..14ef27340e 100644 --- a/activesupport/lib/active_support/core_ext/object/to_json.rb +++ b/activesupport/lib/active_support/core_ext/object/to_json.rb @@ -12,7 +12,7 @@ end [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass| klass.class_eval <<-RUBY, __FILE__, __LINE__ # Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info. - def to_json(options = {}) + def to_json(options = nil) ActiveSupport::JSON.encode(self, options) end RUBY diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 67698c1cff..469ae69258 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -38,7 +38,7 @@ module ActiveSupport attr_reader :options def initialize(options = nil) - @options = options + @options = options || {} @seen = Set.new end @@ -59,7 +59,7 @@ module ActiveSupport def options_for(value) if value.is_a?(Array) || value.is_a?(Hash) # hashes and arrays need to get encoder in the options, so that they can detect circular references - (options || {}).merge(:encoder => self) + options.merge(:encoder => self) else options end -- cgit v1.2.3 From d4457dc32b4d5dc9fde6c852f55a0d43ee021282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 30 Sep 2011 14:20:41 +0200 Subject: Provide read_attribute_for_serialization as the API to serialize attributes. --- activemodel/lib/active_model/serialization.rb | 25 +++++++++++++++++++++++-- activemodel/test/cases/serialization_test.rb | 6 +++--- activeresource/lib/active_resource/base.rb | 4 ++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb index a756b9f205..7bc3f997b5 100644 --- a/activemodel/lib/active_model/serialization.rb +++ b/activemodel/lib/active_model/serialization.rb @@ -78,7 +78,8 @@ module ActiveModel attribute_names -= Array.wrap(except).map(&:to_s) end - hash = attributes.slice(*attribute_names) + hash = {} + attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) } method_names = Array.wrap(options[:methods]).select { |n| respond_to?(n) } method_names.each { |n| hash[n] = send(n) } @@ -95,13 +96,33 @@ module ActiveModel end private + + # Hook method defining how an attribute value should be retrieved for + # serialization. By default this is assumed to be an instance named after + # the attribute. Override this method in subclasses should you need to + # retrieve the value for a given attribute differently: + # + # class MyClass + # include ActiveModel::Validations + # + # def initialize(data = {}) + # @data = data + # end + # + # def read_attribute_for_serialization(key) + # @data[key] + # end + # end + # + alias :read_attribute_for_serialization :send + # Add associations specified via the :include option. # # Expects a block that takes as arguments: # +association+ - name of the association # +records+ - the association record(s) to be serialized # +opts+ - options for the association records - def serializable_add_includes(options = {}) + def serializable_add_includes(options = {}) #:nodoc: return unless include = options[:include] unless include.is_a?(Hash) diff --git a/activemodel/test/cases/serialization_test.rb b/activemodel/test/cases/serialization_test.rb index 29bcdeae67..1ec915d245 100644 --- a/activemodel/test/cases/serialization_test.rb +++ b/activemodel/test/cases/serialization_test.rb @@ -77,12 +77,12 @@ class SerializationTest < ActiveModel::TestCase assert_equal expected , @user.serializable_hash(:methods => [:bar]) end - def test_should_not_call_methods_for_attributes - def @user.name + def test_should_use_read_attribute_for_serialization + def @user.read_attribute_for_serialization(n) "Jon" end - expected = { "name" => "David" } + expected = { "name" => "Jon" } assert_equal expected, @user.serializable_hash(:only => :name) end diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index 1ffd83b91d..03c4cc5b9e 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -1384,6 +1384,10 @@ module ActiveResource private + def read_attribute_for_serialization(n) + attributes[n] + end + # Determine whether the response is allowed to have a body per HTTP 1.1 spec section 4.4.1 def response_code_allows_body?(c) !((100..199).include?(c) || [204,304].include?(c)) -- cgit v1.2.3 From 44791a2bc6611b755b418f1db3ca93f9edec0908 Mon Sep 17 00:00:00 2001 From: Yasuo Honda Date: Fri, 30 Sep 2011 12:05:53 -0400 Subject: Modified how to handle if ActiveRecord is defined. --- railties/lib/rails/test_help.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb index 68f566274d..8d0d8cacac 100644 --- a/railties/lib/rails/test_help.rb +++ b/railties/lib/rails/test_help.rb @@ -24,7 +24,7 @@ if defined?(MiniTest) end end -if defined?(ActiveRecord) +if defined?(ActiveRecord::Base) require 'active_record/test_case' class ActiveSupport::TestCase -- cgit v1.2.3 From b30ffbbfd6da4547449c5cea81ec7627762259c6 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 1 Oct 2011 14:27:12 +0530 Subject: Use of :: in void context Warning removed --- actionpack/lib/sprockets/assets.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake index e29661e4e7..bb5cf6740a 100644 --- a/actionpack/lib/sprockets/assets.rake +++ b/actionpack/lib/sprockets/assets.rake @@ -17,7 +17,7 @@ namespace :assets do end # Ensure that action view is loaded and the appropriate sprockets hooks get executed - ActionView::Base + _ = ActionView::Base config = Rails.application.config config.assets.compile = true -- cgit v1.2.3