Permalink
Browse files

Merge branch 'master' into adequaterecord

* master: (28 commits)
  move AR length validation tests into separate test-case.
  No need for trailing slash on migration path.
  reset `@arel` when modifying a Relation in place.
  PostgreSQL Timestamps always map to `:datetime`.
  [ci skip] Improve formatting and yml
  Fix a typo in the doc of forty_two AR FinderMethod
  Improve readability of contributing to rails guide. [ci skip]
  Precompile the image we're referencing, too.
  `ActiveRecord::Base.no_touching` no longer triggers callbacks or start empty transactions.
  Fixed an issue with migrating legacy json cookies.
  Correct comment [ci skip]
  Perfer to define methods instead of calling test
  Fix syntax error
  Add CHANGELOG entry for #14757 [ci skip]
  Fix run-on sentences and improve grammar [skip ci]
  Add test for using ActionView::Helpers::FormHelper.label with block and html
  select! renamed to avoid name collision Array#select!
  Rearrange deck chairs on the titanic. Organize connection handling test cases.
  Change favicon_link_tag helper mimetype from image/vnd.microsoft.icon to image/x-icon.
  ActionController::Renderers documentation fix
  ...
  • Loading branch information...
tenderlove committed Apr 25, 2014
2 parents b395265 + 7fe5ae8 commit ccdeb43d2e06fb87c1fb84e979c4f7775e7ed105
Showing with 634 additions and 380 deletions.
  1. +2 −2 actionmailer/lib/action_mailer/base.rb
  2. +13 −0 actionpack/CHANGELOG.md
  3. +29 −35 actionpack/lib/abstract_controller/callbacks.rb
  4. +2 −2 actionpack/lib/action_controller/metal/renderers.rb
  5. +2 −2 actionpack/lib/action_dispatch/middleware/cookies.rb
  6. +117 −0 actionpack/test/dispatch/cookies_test.rb
  7. +15 −0 actionview/CHANGELOG.md
  8. +3 −3 actionview/lib/action_view/helpers/asset_tag_helper.rb
  9. +1 −0 actionview/lib/action_view/helpers/form_helper.rb
  10. +3 −3 actionview/test/template/asset_tag_helper_test.rb
  11. +7 −0 actionview/test/template/form_helper_test.rb
  12. +40 −0 activerecord/CHANGELOG.md
  13. +1 −1 activerecord/lib/active_record/associations/preloader/association.rb
  14. +1 −1 activerecord/lib/active_record/associations/preloader/through_association.rb
  15. +4 −2 activerecord/lib/active_record/associations/through_association.rb
  16. +1 −1 activerecord/lib/active_record/base.rb
  17. +1 −6 activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
  18. +1 −1 activerecord/lib/active_record/relation/delegation.rb
  19. +1 −1 activerecord/lib/active_record/relation/finder_methods.rb
  20. +9 −1 activerecord/lib/active_record/relation/merger.rb
  21. +14 −2 activerecord/lib/active_record/relation/query_methods.rb
  22. +16 −4 activerecord/test/cases/associations/has_many_through_associations_test.rb
  23. +0 −56 activerecord/test/cases/connection_adapters/abstract_adapter_test.rb
  24. +54 −0 activerecord/test/cases/connection_adapters/adapter_leasing_test.rb
  25. +0 −193 activerecord/test/cases/connection_adapters/connection_handler_test.rb
  26. +192 −0 activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb
  27. +1 −1 activerecord/test/cases/migrator_test.rb
  28. +6 −1 activerecord/test/cases/relation/mutation_test.rb
  29. +20 −1 activerecord/test/cases/timestamp_test.rb
  30. +1 −42 activerecord/test/cases/validations/association_validation_test.rb
  31. +47 −0 activerecord/test/cases/validations/length_validation_test.rb
  32. +4 −0 activerecord/test/models/post.rb
  33. +2 −0 activerecord/test/models/reader.rb
  34. +1 −1 activesupport/lib/active_support/core_ext/string/inflections.rb
  35. +3 −3 activesupport/lib/active_support/inflector/methods.rb
  36. +5 −0 activesupport/test/core_ext/string_ext_test.rb
  37. +5 −5 guides/source/contributing_to_ruby_on_rails.md
  38. +8 −8 guides/source/getting_started.md
  39. +2 −2 railties/test/application/assets_test.rb
@@ -154,7 +154,7 @@ module ActionMailer
# * signup_notification.text.erb
# * signup_notification.html.erb
# * signup_notification.xml.builder
# * signup_notification.yaml.erb
# * signup_notification.yml.erb
#
# Each would be rendered and added as a separate part to the message, with the corresponding content
# type. The content type for the entire message is automatically set to <tt>multipart/alternative</tt>,
@@ -325,7 +325,7 @@ module ActionMailer
# directory can be configured using the <tt>preview_path</tt> option which has a default
# of <tt>test/mailers/previews</tt>:
#
# config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
# config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
#
# An overview of all previews is accessible at <tt>http://localhost:3000/rails/mailers</tt>
# on a running development server instance.
View
@@ -1,3 +1,16 @@
* Fixed an issue with migrating legacy json cookies.
Previously, the `VerifyAndUpgradeLegacySignedMessage` assumes all incoming
cookies are marshal-encoded. This is not the case when `secret_token` is
used in conjunction with the `:json` or `:hybrid` serializer.
In those case, when upgrading to use `secret_key_base`, this would cause a
`TypeError: incompatible marshal file format` and a 500 error for the user.
Fixes #14774.
*Godfrey Chan*
* Make URL escaping more consistent:
1. Escape '%' characters in URLs - only unescaped data should be passed to URL helpers
@@ -178,41 +178,35 @@ def _insert_callbacks(callbacks, block = nil)
# set up before_action, prepend_before_action, skip_before_action, etc.
# for each of before, after, and around.
[:before, :after, :around].each do |callback|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
# Append a before, after or around callback. See _insert_callbacks
# for details on the allowed parameters.
def #{callback}_action(*names, &blk) # def before_action(*names, &blk)
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
set_callback(:process_action, :#{callback}, name, options) # set_callback(:process_action, :before, name, options)
end # end
end # end
alias_method :#{callback}_filter, :#{callback}_action
# Prepend a before, after or around callback. See _insert_callbacks
# for details on the allowed parameters.
def prepend_#{callback}_action(*names, &blk) # def prepend_before_action(*names, &blk)
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
set_callback(:process_action, :#{callback}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
end # end
end # end
alias_method :prepend_#{callback}_filter, :prepend_#{callback}_action
# Skip a before, after or around callback. See _insert_callbacks
# for details on the allowed parameters.
def skip_#{callback}_action(*names) # def skip_before_action(*names)
_insert_callbacks(names) do |name, options| # _insert_callbacks(names) do |name, options|
skip_callback(:process_action, :#{callback}, name, options) # skip_callback(:process_action, :before, name, options)
end # end
end # end
alias_method :skip_#{callback}_filter, :skip_#{callback}_action
# *_action is the same as append_*_action
alias_method :append_#{callback}_action, :#{callback}_action # alias_method :append_before_action, :before_action
alias_method :append_#{callback}_filter, :#{callback}_action # alias_method :append_before_filter, :before_action
RUBY_EVAL
define_method "#{callback}_action" do |*names, &blk|
_insert_callbacks(names, blk) do |name, options|
set_callback(:process_action, callback, name, options)
end
end
alias_method :"#{callback}_filter", :"#{callback}_action"
define_method "prepend_#{callback}_action" do |*names, &blk|
_insert_callbacks(names, blk) do |name, options|
set_callback(:process_action, callback, name, options.merge(:prepend => true))
end
end
alias_method :"prepend_#{callback}_filter", :"prepend_#{callback}_action"
# Skip a before, after or around callback. See _insert_callbacks
# for details on the allowed parameters.
define_method "skip_#{callback}_action" do |*names|
_insert_callbacks(names) do |name, options|
skip_callback(:process_action, callback, name, options)
end
end
alias_method :"skip_#{callback}_filter", :"skip_#{callback}_action"
# *_action is the same as append_*_action
alias_method :"append_#{callback}_action", :"#{callback}_action" # alias_method :append_before_action, :before_action
alias_method :"append_#{callback}_filter", :"#{callback}_action" # alias_method :append_before_filter, :before_action
end
end
end
@@ -42,8 +42,8 @@ def _handle_render_options(options)
nil
end
# Hash of available renderers, mapping a renderer name to its proc.
# Default keys are <tt>:json</tt>, <tt>:js</tt>, <tt>:xml</tt>.
# A Set containing renderer names that correspond to available renderer procs.
# Default values are <tt>:json</tt>, <tt>:js</tt>, <tt>:xml</tt>.
RENDERERS = Set.new
# Adds a new renderer to call within controller actions.
@@ -176,11 +176,11 @@ def signed_or_encrypted
module VerifyAndUpgradeLegacySignedMessage
def initialize(*args)
super
@legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token])
@legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token], serializer: NullSerializer)
end
def verify_and_upgrade_legacy_signed_message(name, signed_message)
@legacy_verifier.verify(signed_message).tap do |value|
deserialize(name, @legacy_verifier.verify(signed_message)).tap do |value|
self[name] = { value: value }
end
rescue ActiveSupport::MessageVerifier::InvalidSignature
@@ -681,6 +681,123 @@ def test_legacy_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_c
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :json
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate(45)
@request.headers["Cookie"] = "user_id=#{legacy_value}"
get :get_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
assert_equal 45, verifier.verify(@response.cookies["user_id"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_json_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :json
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
@request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate('bar')
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate(45)
@request.headers["Cookie"] = "user_id=#{legacy_value}"
get :get_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
assert_equal 45, verifier.verify(@response.cookies["user_id"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_hybrid_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
@request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate('bar')
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_marshal_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate(45)
@request.headers["Cookie"] = "user_id=#{legacy_value}"
get :get_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
assert_equal 45, verifier.verify(@response.cookies["user_id"])
end
def test_legacy_marshal_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_hybrid_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
@request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate('bar')
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_signed_cookie_is_treated_as_nil_by_signed_cookie_jar_if_tampered
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
View
@@ -1,3 +1,18 @@
* Change `favicon_link_tag` default mimetype from `image/vnd.microsoft.icon` to
`image/x-icon`.
Before:
#=> favicon_link_tag 'myicon.ico'
<link href="/assets/myicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
After:
#=> favicon_link_tag 'myicon.ico'
<link href="/assets/myicon.ico" rel="shortcut icon" type="image/x-icon" />
*Geoffroy Lorieux*
* Remove wrapping div with inline styles for hidden form fields.
We are dropping HTML 4.01 and XHTML strict compliance since input tags directly
@@ -149,12 +149,12 @@ def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
# ==== Options
#
# * <tt>:rel</tt> - Specify the relation of this link, defaults to 'shortcut icon'
# * <tt>:type</tt> - Override the auto-generated mime type, defaults to 'image/vnd.microsoft.icon'
# * <tt>:type</tt> - Override the auto-generated mime type, defaults to 'image/x-icon'
#
# ==== Examples
#
# favicon_link_tag 'myicon.ico'
# # => <link href="/assets/myicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
# # => <link href="/assets/myicon.ico" rel="shortcut icon" type="image/x-icon" />
#
# Mobile Safari looks for a different <link> tag, pointing to an image that
# will be used if you add the page to the home screen of an iPod Touch, iPhone, or iPad.
@@ -165,7 +165,7 @@ def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
def favicon_link_tag(source='favicon.ico', options={})
tag('link', {
:rel => 'shortcut icon',
:type => 'image/vnd.microsoft.icon',
:type => 'image/x-icon',
:href => path_to_image(source)
}.merge!(options.symbolize_keys))
end
@@ -746,6 +746,7 @@ def fields_for(record_name, record_object = nil, options = {}, &block)
# label(:post, :terms) do
# 'Accept <a href="/terms">Terms</a>.'.html_safe
# end
# # => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label>
def label(object_name, method, content_or_options = nil, options = nil, &block)
Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
end
@@ -195,9 +195,9 @@ def url_for(*args)
}
FaviconLinkToTag = {
%(favicon_link_tag) => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />),
%(favicon_link_tag 'favicon.ico') => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />),
%(favicon_link_tag 'favicon.ico', :rel => 'foo') => %(<link href="/images/favicon.ico" rel="foo" type="image/vnd.microsoft.icon" />),
%(favicon_link_tag) => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/x-icon" />),
%(favicon_link_tag 'favicon.ico') => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/x-icon" />),
%(favicon_link_tag 'favicon.ico', :rel => 'foo') => %(<link href="/images/favicon.ico" rel="foo" type="image/x-icon" />),
%(favicon_link_tag 'favicon.ico', :rel => 'foo', :type => 'bar') => %(<link href="/images/favicon.ico" rel="foo" type="bar" />),
%(favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png') => %(<link href="/images/mb-icon.png" rel="apple-touch-icon" type="image/png" />)
}
@@ -265,6 +265,13 @@ def test_label_with_block
)
end
def test_label_with_block_and_html
assert_dom_equal(
'<label for="post_terms">Accept <a href="/terms">Terms</a>.</label>',
label(:post, :terms) { 'Accept <a href="/terms">Terms</a>.'.html_safe }
)
end
def test_label_with_block_and_options
assert_dom_equal(
'<label for="my_for">The title, please:</label>',
View
@@ -1,3 +1,43 @@
* Reset the cache when modifying a Relation with cached Arel.
Additionally display a warning message to make the user aware.
*Yves Senn*
* PostgreSQL should internally use `:datetime` consistently for TimeStamp. Assures
different spellings of timestamps are treated the same.
Example:
mytimestamp.simplified_type('timestamp without time zone')
# => :datetime
mytimestamp.simplified_type('timestamp(6) without time zone')
# => also :datetime (previously would be :timestamp)
See #14513.
*Jefferson Lai*
* `ActiveRecord::Base.no_touching` no longer triggers callbacks or start empty transactions.
Fixes #14841.
*Lucas Mazza*
* Fix name collision with `Array#select!` with `Relation#select!`.
Fixes #14752.
*Earl St Sauver*
* Fixed unexpected behavior for `has_many :through` associations going through a scoped `has_many`.
If a `has_many` association is adjusted using a scope, and another `has_many :through`
uses this association, then the scope adjustment is unexpectedly neglected.
Fixes #14537.
*Jan Habermann*
* `@destroyed` should always be set to `false` when an object is duped.
*Kuldeep Aggarwal*
@@ -119,7 +119,7 @@ def build_scope
scope.references_values = Array(values[:references]) + Array(preload_values[:references])
scope.bind_values = (reflection_binds + preload_binds)
scope.select! preload_values[:select] || values[:select] || table[Arel.star]
scope._select! preload_values[:select] || values[:select] || table[Arel.star]
scope.includes! preload_values[:includes] || values[:includes]
if preload_values.key? :order
Oops, something went wrong.

56 comments on commit ccdeb43

@evanphx

This comment has been minimized.

Show comment
Hide comment
@evanphx

evanphx Apr 25, 2014

Contributor

👍

Contributor

evanphx replied Apr 25, 2014

👍

@arunagw

This comment has been minimized.

Show comment
Hide comment
@arunagw

arunagw Apr 25, 2014

Member

❤️

Member

arunagw replied Apr 25, 2014

❤️

@jessicard

This comment has been minimized.

Show comment
Hide comment
@jessicard

jessicard Apr 25, 2014

WAIT THIS WAS 5 HOURS AGO

jessicard replied Apr 25, 2014

WAIT THIS WAS 5 HOURS AGO

@jhawthorn

This comment has been minimized.

Show comment
Hide comment
@jhawthorn

jhawthorn Apr 25, 2014

Contributor

👍 ❤️

Contributor

jhawthorn replied Apr 25, 2014

👍 ❤️

@katiesvt

This comment has been minimized.

Show comment
Hide comment
@katiesvt

katiesvt replied Apr 25, 2014

👍

@jessicard

This comment has been minimized.

Show comment
Hide comment
@jessicard

jessicard Apr 25, 2014

but ❤️

jessicard replied Apr 25, 2014

but ❤️

@Stephenitis

This comment has been minimized.

Show comment
Hide comment
@Stephenitis

Stephenitis replied Apr 25, 2014

👍

@danrabinowitz

This comment has been minimized.

Show comment
Hide comment
@danrabinowitz

danrabinowitz replied Apr 25, 2014

👍

@nbudin

This comment has been minimized.

Show comment
Hide comment
@nbudin

nbudin Apr 25, 2014

Contributor

👍

Contributor

nbudin replied Apr 25, 2014

👍

@mrfoto

This comment has been minimized.

Show comment
Hide comment
@mrfoto

mrfoto Apr 25, 2014

Woohoo 🎉 👍

mrfoto replied Apr 25, 2014

Woohoo 🎉 👍

@melanoma

This comment has been minimized.

Show comment
Hide comment
@melanoma

melanoma replied Apr 25, 2014

👍

@steindekker

This comment has been minimized.

Show comment
Hide comment
@steindekker

steindekker replied Apr 25, 2014

👍

@olivierlacan

This comment has been minimized.

Show comment
Hide comment
@olivierlacan

olivierlacan Apr 25, 2014

Contributor

👍 💃

Contributor

olivierlacan replied Apr 25, 2014

👍 💃

@arturocadena

This comment has been minimized.

Show comment
Hide comment
@arturocadena

arturocadena replied Apr 25, 2014

👍 ❤️

@sferik

This comment has been minimized.

Show comment
Hide comment
@sferik

sferik Apr 25, 2014

Contributor

😐 Very adequate.

Contributor

sferik replied Apr 25, 2014

😐 Very adequate.

@sebasoga

This comment has been minimized.

Show comment
Hide comment
@sebasoga

sebasoga Apr 25, 2014

Contributor

👍

Contributor

sebasoga replied Apr 25, 2014

👍

@dissolved

This comment has been minimized.

Show comment
Hide comment
@dissolved

dissolved Apr 25, 2014

Contributor

👍❤️

Contributor

dissolved replied Apr 25, 2014

👍❤️

@keithpitt

This comment has been minimized.

Show comment
Hide comment
@keithpitt

keithpitt replied Apr 25, 2014

👍

@brianfoshee

This comment has been minimized.

Show comment
Hide comment
@brianfoshee

brianfoshee Apr 25, 2014

Contributor

👍

Contributor

brianfoshee replied Apr 25, 2014

👍

@Willianvdv

This comment has been minimized.

Show comment
Hide comment
@Willianvdv

Willianvdv replied Apr 25, 2014

😺

@reinaris

This comment has been minimized.

Show comment
Hide comment
@reinaris

reinaris Apr 25, 2014

:couplekiss:

reinaris replied Apr 25, 2014

:couplekiss:

@dpmcnevin

This comment has been minimized.

Show comment
Hide comment
@dpmcnevin

dpmcnevin Apr 25, 2014

Contributor

👍 !

Contributor

dpmcnevin replied Apr 25, 2014

👍 !

@skwp

This comment has been minimized.

Show comment
Hide comment
@skwp

skwp Apr 25, 2014

not only did @tenderlove make an awesome commit, but he traveled back in time to do it 👍

skwp replied Apr 25, 2014

not only did @tenderlove make an awesome commit, but he traveled back in time to do it 👍

@epylinkn

This comment has been minimized.

Show comment
Hide comment
@epylinkn

epylinkn Apr 25, 2014

⛵️ - 5 hours ago =P

And thanks for the stickers!

epylinkn replied Apr 25, 2014

⛵️ - 5 hours ago =P

And thanks for the stickers!

@marzapower

This comment has been minimized.

Show comment
Hide comment
@marzapower

marzapower Apr 25, 2014

Contributor

👍

Contributor

marzapower replied Apr 25, 2014

👍

@skchoi

This comment has been minimized.

Show comment
Hide comment
@skchoi

skchoi Apr 25, 2014

😸 👍

skchoi replied Apr 25, 2014

😸 👍

@tonyta

This comment has been minimized.

Show comment
Hide comment
@tonyta

tonyta Apr 25, 2014

Contributor

👍

Contributor

tonyta replied Apr 25, 2014

👍

@y-yagi

This comment has been minimized.

Show comment
Hide comment
@y-yagi

y-yagi Apr 25, 2014

Member

👍

Member

y-yagi replied Apr 25, 2014

👍

@mbhnyc

This comment has been minimized.

Show comment
Hide comment
@mbhnyc

mbhnyc Apr 25, 2014

Contributor

Congrats and excellent talk!!!

Contributor

mbhnyc replied Apr 25, 2014

Congrats and excellent talk!!!

@Irio

This comment has been minimized.

Show comment
Hide comment
@Irio

Irio replied Apr 26, 2014

👍

@mogox

This comment has been minimized.

Show comment
Hide comment
@mogox

mogox Apr 26, 2014

👍 💯 thanks!

mogox replied Apr 26, 2014

👍 💯 thanks!

@adomokos

This comment has been minimized.

Show comment
Hide comment
@adomokos

adomokos Apr 26, 2014

Contributor

I am so glad the Internet(s) worked! Good job! 👍

Contributor

adomokos replied Apr 26, 2014

I am so glad the Internet(s) worked! Good job! 👍

@danielberkompas

This comment has been minimized.

Show comment
Hide comment

danielberkompas replied Apr 26, 2014

👍

@yijia-zhan

This comment has been minimized.

Show comment
Hide comment
@yijia-zhan

yijia-zhan replied Apr 26, 2014

👍

@raphaelcosta

This comment has been minimized.

Show comment
Hide comment
@raphaelcosta

raphaelcosta replied Apr 26, 2014

👍

@wejrowski

This comment has been minimized.

Show comment
Hide comment
@wejrowski

wejrowski replied Apr 26, 2014

👍 🐈

@fredwu

This comment has been minimized.

Show comment
Hide comment
@fredwu

fredwu Apr 26, 2014

Contributor

:shipit: ❤️

Contributor

fredwu replied Apr 26, 2014

:shipit: ❤️

@toctan

This comment has been minimized.

Show comment
Hide comment
@toctan

toctan Apr 26, 2014

👍 ❤️

toctan replied Apr 26, 2014

👍 ❤️

@wpp

This comment has been minimized.

Show comment
Hide comment
@wpp

wpp Apr 26, 2014

👍 ❤️

wpp replied Apr 26, 2014

👍 ❤️

@imkmf

This comment has been minimized.

Show comment
Hide comment
@imkmf

imkmf Apr 26, 2014

Contributor

👍 👍 👍 !!!!

Contributor

imkmf replied Apr 26, 2014

👍 👍 👍 !!!!

@virusman

This comment has been minimized.

Show comment
Hide comment
@virusman

virusman Apr 26, 2014

Contributor

💪

Contributor

virusman replied Apr 26, 2014

💪

@csouls

This comment has been minimized.

Show comment
Hide comment
@csouls

csouls replied Apr 26, 2014

👍

@jstenhouse

This comment has been minimized.

Show comment
Hide comment
@jstenhouse

jstenhouse replied Apr 26, 2014

👍

@sadiqmmm

This comment has been minimized.

Show comment
Hide comment
@sadiqmmm

sadiqmmm Apr 26, 2014

Awesome! Thanks ! :) 👍

sadiqmmm replied Apr 26, 2014

Awesome! Thanks ! :) 👍

@justinweiss

This comment has been minimized.

Show comment
Hide comment
@justinweiss

justinweiss Apr 26, 2014

Contributor

👍

Contributor

justinweiss replied Apr 26, 2014

👍

@00ec454

This comment has been minimized.

Show comment
Hide comment
@00ec454

00ec454 replied Apr 26, 2014

👍

@sjahandideh

This comment has been minimized.

Show comment
Hide comment
@sjahandideh

sjahandideh Apr 28, 2014

👍 @tenderlove you didn't re-run tests before merging though!

sjahandideh replied Apr 28, 2014

👍 @tenderlove you didn't re-run tests before merging though!

@rraub

This comment has been minimized.

Show comment
Hide comment
@rraub

rraub replied Apr 28, 2014

👍

@florida

This comment has been minimized.

Show comment
Hide comment
@florida

florida Apr 28, 2014

awesome! 👍 🌈

florida replied Apr 28, 2014

awesome! 👍 🌈

@taylorbrooks

This comment has been minimized.

Show comment
Hide comment
@taylorbrooks

taylorbrooks Apr 29, 2014

👍 :shipit: Great job at RailsConf @tenderlove

taylorbrooks replied Apr 29, 2014

👍 :shipit: Great job at RailsConf @tenderlove

@robdvr

This comment has been minimized.

Show comment
Hide comment
@robdvr

robdvr replied Apr 30, 2014

👍

@hsbt

This comment has been minimized.

Show comment
Hide comment
@hsbt

hsbt Apr 30, 2014

Contributor

⚡️

Contributor

hsbt replied Apr 30, 2014

⚡️

@ivangranados

This comment has been minimized.

Show comment
Hide comment
@ivangranados

ivangranados replied May 3, 2014

👍

@JuanitoFatas

This comment has been minimized.

Show comment
Hide comment
@JuanitoFatas

JuanitoFatas May 3, 2014

Contributor

👍

Contributor

JuanitoFatas replied May 3, 2014

👍

@dalpo

This comment has been minimized.

Show comment
Hide comment
@dalpo

dalpo May 6, 2014

Much love ❤️

dalpo replied May 6, 2014

Much love ❤️

@zoras

This comment has been minimized.

Show comment
Hide comment
@zoras

zoras May 7, 2014

❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️

zoras replied May 7, 2014

❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️

Please sign in to comment.