Skip to content

Commit

Permalink
Merge branch 'master' into adequaterecord
Browse files Browse the repository at this point in the history
* 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 ccdeb43
Show file tree
Hide file tree
Showing 39 changed files with 634 additions and 380 deletions.
4 changes: 2 additions & 2 deletions actionmailer/lib/action_mailer/base.rb
Expand Up @@ -154,7 +154,7 @@ module ActionMailer
# * signup_notification.text.erb # * signup_notification.text.erb
# * signup_notification.html.erb # * signup_notification.html.erb
# * signup_notification.xml.builder # * 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 # 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>, # type. The content type for the entire message is automatically set to <tt>multipart/alternative</tt>,
Expand Down Expand Up @@ -325,7 +325,7 @@ module ActionMailer
# directory can be configured using the <tt>preview_path</tt> option which has a default # directory can be configured using the <tt>preview_path</tt> option which has a default
# of <tt>test/mailers/previews</tt>: # 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> # An overview of all previews is accessible at <tt>http://localhost:3000/rails/mailers</tt>
# on a running development server instance. # on a running development server instance.
Expand Down
13 changes: 13 additions & 0 deletions actionpack/CHANGELOG.md
@@ -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: * Make URL escaping more consistent:


1. Escape '%' characters in URLs - only unescaped data should be passed to URL helpers 1. Escape '%' characters in URLs - only unescaped data should be passed to URL helpers
Expand Down
64 changes: 29 additions & 35 deletions actionpack/lib/abstract_controller/callbacks.rb
Expand Up @@ -178,41 +178,35 @@ def _insert_callbacks(callbacks, block = nil)
# set up before_action, prepend_before_action, skip_before_action, etc. # set up before_action, prepend_before_action, skip_before_action, etc.
# for each of before, after, and around. # for each of before, after, and around.
[:before, :after, :around].each do |callback| [:before, :after, :around].each do |callback|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 define_method "#{callback}_action" do |*names, &blk|
# Append a before, after or around callback. See _insert_callbacks _insert_callbacks(names, blk) do |name, options|
# for details on the allowed parameters. set_callback(:process_action, callback, name, options)
def #{callback}_action(*names, &blk) # def before_action(*names, &blk) end
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options| end
set_callback(:process_action, :#{callback}, name, options) # set_callback(:process_action, :before, name, options)
end # end alias_method :"#{callback}_filter", :"#{callback}_action"
end # end
define_method "prepend_#{callback}_action" do |*names, &blk|
alias_method :#{callback}_filter, :#{callback}_action _insert_callbacks(names, blk) do |name, options|
set_callback(:process_action, callback, name, options.merge(:prepend => true))
# Prepend a before, after or around callback. See _insert_callbacks end
# for details on the allowed parameters. end
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| alias_method :"prepend_#{callback}_filter", :"prepend_#{callback}_action"
set_callback(:process_action, :#{callback}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
end # end # Skip a before, after or around callback. See _insert_callbacks
end # end # for details on the allowed parameters.
define_method "skip_#{callback}_action" do |*names|
alias_method :prepend_#{callback}_filter, :prepend_#{callback}_action _insert_callbacks(names) do |name, options|
skip_callback(:process_action, callback, name, options)
# Skip a before, after or around callback. See _insert_callbacks end
# for details on the allowed parameters. end
def skip_#{callback}_action(*names) # def skip_before_action(*names)
_insert_callbacks(names) do |name, options| # _insert_callbacks(names) do |name, options| alias_method :"skip_#{callback}_filter", :"skip_#{callback}_action"
skip_callback(:process_action, :#{callback}, name, options) # skip_callback(:process_action, :before, name, options)
end # end # *_action is the same as append_*_action
end # end 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
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
end end
end end
end end
Expand Down
4 changes: 2 additions & 2 deletions actionpack/lib/action_controller/metal/renderers.rb
Expand Up @@ -42,8 +42,8 @@ def _handle_render_options(options)
nil nil
end end


# Hash of available renderers, mapping a renderer name to its proc. # A Set containing renderer names that correspond to available renderer procs.
# Default keys are <tt>:json</tt>, <tt>:js</tt>, <tt>:xml</tt>. # Default values are <tt>:json</tt>, <tt>:js</tt>, <tt>:xml</tt>.
RENDERERS = Set.new RENDERERS = Set.new


# Adds a new renderer to call within controller actions. # Adds a new renderer to call within controller actions.
Expand Down
4 changes: 2 additions & 2 deletions actionpack/lib/action_dispatch/middleware/cookies.rb
Expand Up @@ -176,11 +176,11 @@ def signed_or_encrypted
module VerifyAndUpgradeLegacySignedMessage module VerifyAndUpgradeLegacySignedMessage
def initialize(*args) def initialize(*args)
super super
@legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token]) @legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token], serializer: NullSerializer)
end end


def verify_and_upgrade_legacy_signed_message(name, signed_message) 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 } self[name] = { value: value }
end end
rescue ActiveSupport::MessageVerifier::InvalidSignature rescue ActiveSupport::MessageVerifier::InvalidSignature
Expand Down
117 changes: 117 additions & 0 deletions actionpack/test/dispatch/cookies_test.rb
Expand Up @@ -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"]) assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end 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 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_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
Expand Down
15 changes: 15 additions & 0 deletions actionview/CHANGELOG.md
@@ -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. * Remove wrapping div with inline styles for hidden form fields.


We are dropping HTML 4.01 and XHTML strict compliance since input tags directly We are dropping HTML 4.01 and XHTML strict compliance since input tags directly
Expand Down
6 changes: 3 additions & 3 deletions actionview/lib/action_view/helpers/asset_tag_helper.rb
Expand Up @@ -149,12 +149,12 @@ def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
# ==== Options # ==== Options
# #
# * <tt>:rel</tt> - Specify the relation of this link, defaults to 'shortcut icon' # * <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 # ==== Examples
# #
# favicon_link_tag 'myicon.ico' # 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 # 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. # will be used if you add the page to the home screen of an iPod Touch, iPhone, or iPad.
Expand All @@ -165,7 +165,7 @@ def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
def favicon_link_tag(source='favicon.ico', options={}) def favicon_link_tag(source='favicon.ico', options={})
tag('link', { tag('link', {
:rel => 'shortcut icon', :rel => 'shortcut icon',
:type => 'image/vnd.microsoft.icon', :type => 'image/x-icon',
:href => path_to_image(source) :href => path_to_image(source)
}.merge!(options.symbolize_keys)) }.merge!(options.symbolize_keys))
end end
Expand Down
1 change: 1 addition & 0 deletions actionview/lib/action_view/helpers/form_helper.rb
Expand Up @@ -746,6 +746,7 @@ def fields_for(record_name, record_object = nil, options = {}, &block)
# label(:post, :terms) do # label(:post, :terms) do
# 'Accept <a href="/terms">Terms</a>.'.html_safe # 'Accept <a href="/terms">Terms</a>.'.html_safe
# end # end
# # => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label>
def label(object_name, method, content_or_options = nil, options = nil, &block) 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) Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
end end
Expand Down
6 changes: 3 additions & 3 deletions actionview/test/template/asset_tag_helper_test.rb
Expand Up @@ -195,9 +195,9 @@ def url_for(*args)
} }


FaviconLinkToTag = { FaviconLinkToTag = {
%(favicon_link_tag) => %(<link href="/images/favicon.ico" rel="shortcut icon" 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/vnd.microsoft.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/vnd.microsoft.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 '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" />) %(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" />)
} }
Expand Down
7 changes: 7 additions & 0 deletions actionview/test/template/form_helper_test.rb
Expand Up @@ -265,6 +265,13 @@ def test_label_with_block
) )
end 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 def test_label_with_block_and_options
assert_dom_equal( assert_dom_equal(
'<label for="my_for">The title, please:</label>', '<label for="my_for">The title, please:</label>',
Expand Down
40 changes: 40 additions & 0 deletions activerecord/CHANGELOG.md
@@ -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. * `@destroyed` should always be set to `false` when an object is duped.


*Kuldeep Aggarwal* *Kuldeep Aggarwal*
Expand Down
Expand Up @@ -119,7 +119,7 @@ def build_scope
scope.references_values = Array(values[:references]) + Array(preload_values[:references]) scope.references_values = Array(values[:references]) + Array(preload_values[:references])
scope.bind_values = (reflection_binds + preload_binds) 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] scope.includes! preload_values[:includes] || values[:includes]


if preload_values.key? :order if preload_values.key? :order
Expand Down

56 comments on commit ccdeb43

@evanphx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@arunagw
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@jessicard
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WAIT THIS WAS 5 HOURS AGO

@jhawthorn
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ❤️

@katiesvt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@jessicard
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but ❤️

@Stephenitis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@danrabinowitz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@nbudin
Copy link

@nbudin nbudin commented on ccdeb43 Apr 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@miharekar
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woohoo 🎉 👍

@melanoma
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@steindekker
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@olivierlacan
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 💃

@arturocadena
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ❤️

@sferik
Copy link
Contributor

@sferik sferik commented on ccdeb43 Apr 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😐 Very adequate.

@sogamoso
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@dissolved
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍❤️

@keithpitt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@brianfoshee
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@Willianvdv
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😺

@reinaris
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💏

@dpmcnevin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 !

@skwp
Copy link

@skwp skwp commented on ccdeb43 Apr 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@epylinkn
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛵ - 5 hours ago =P

And thanks for the stickers!

@marzapower
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@skchoi
Copy link

@skchoi skchoi commented on ccdeb43 Apr 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😸 👍

@tonyta
Copy link
Contributor

@tonyta tonyta commented on ccdeb43 Apr 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@y-yagi
Copy link
Member

@y-yagi y-yagi commented on ccdeb43 Apr 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mbhnyc
Copy link
Contributor

@mbhnyc mbhnyc commented on ccdeb43 Apr 25, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congrats and excellent talk!!!

@Irio
Copy link

@Irio Irio commented on ccdeb43 Apr 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mogox
Copy link

@mogox mogox commented on ccdeb43 Apr 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 💯 thanks!

@adomokos
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@danielberkompas
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@yijia-zhan
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@raphaelcosta
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@wejrowski
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 🐈

@fredwu
Copy link
Contributor

@fredwu fredwu commented on ccdeb43 Apr 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit: ❤️

@toctan
Copy link

@toctan toctan commented on ccdeb43 Apr 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ❤️

@wpp
Copy link

@wpp wpp commented on ccdeb43 Apr 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ❤️

@kristianfreeman
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍 !!!!

@virusman
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💪

@csouls
Copy link

@csouls csouls commented on ccdeb43 Apr 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@jstenhouse
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@sadiqmmm
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Thanks ! :) 👍

@justinweiss
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@00ec454
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@sjahandideh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@rraub
Copy link

@rraub rraub commented on ccdeb43 Apr 28, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@florida
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome! 👍 🌈

@taylorbrooks
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 :shipit: Great job at RailsConf @tenderlove

@robdvr
Copy link

@robdvr robdvr commented on ccdeb43 Apr 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@hsbt
Copy link
Contributor

@hsbt hsbt commented on ccdeb43 Apr 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ivangranados
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@JuanitoFatas
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@dalpo
Copy link

@dalpo dalpo commented on ccdeb43 May 6, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much love ❤️

@zoras
Copy link

@zoras zoras commented on ccdeb43 May 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Please sign in to comment.