-
-
Save bf4/8940203 to your computer and use it in GitHub Desktop.
# Rails 3.2 support for HTTP PATCH. | |
fail "Remove this patch" if Rails::VERSION::MAJOR > 3 | |
# see http://weblog.rubyonrails.org/2012/2/26/edge-rails-patch-is-the-new-primary-http-method-for-updates/ | |
# https://github.com/rails/rails/pull/505 | |
# Be very conservative not to monkey-patch any methods until | |
# the relevant files are loaded. | |
ActiveSupport.on_load(:action_controller) do | |
ActionDispatch::Request.instance_eval do | |
# Is this a PATCH request? | |
# Equivalent to <tt>request.request_method == :patch</tt>. | |
def patch? | |
HTTP_METHOD_LOOKUP[request_method] == :patch | |
end | |
end | |
module ActionDispatch::Routing | |
HTTP_METHODS << :patch unless HTTP_METHODS.include?(:patch) | |
end | |
ActionDispatch::Routing::Mapper::HttpHelpers.instance_eval do | |
# Define a route that only recognizes HTTP PATCH. | |
# For supported arguments, see <tt>Base#match</tt>. | |
# | |
# Example: | |
# | |
# patch 'bacon', :to => 'food#bacon' | |
def patch(*args, &block) | |
map_method(:patch, *args, &block) | |
end | |
end | |
ActionDispatch::Integration::RequestHelpers.instance_eval do | |
# Performs a PATCH request with the given parameters. See +#get+ for more | |
# details. | |
def patch(path, parameters = nil, headers = nil) | |
process :patch, path, parameters, headers | |
end | |
# Performs a PATCH request, following any subsequent redirect. | |
# See +request_via_redirect+ for more information. | |
def patch_via_redirect(path, parameters = nil, headers = nil) | |
request_via_redirect(:patch, path, parameters, headers) | |
end | |
end | |
ActionDispatch::Integration::Runner.class_eval do | |
%w(patch).each do |method| | |
define_method(method) do |*args| | |
reset! unless integration_session | |
# reset the html_document variable, but only for new get/post calls | |
@html_document = nil unless method.in?(["cookies", "assigns"]) | |
integration_session.__send__(method, *args).tap do | |
copy_session_variables! | |
end | |
end | |
end | |
end | |
module ActionController::TestCase::Behavior | |
def patch(action, parameters = nil, session = nil, flash = nil) | |
process(action, parameters, session, flash, "PATCH") | |
end | |
end | |
class ActionController::Responder | |
ACTIONS_FOR_VERBS.update(:patch => :edit) | |
delegate :patch?, :to => :request | |
end | |
ActionView::Helpers::FormHelper.instance_eval do | |
# = Action View Form Helpers | |
def apply_form_for_options!(record, object, options) #:nodoc: | |
object = convert_to_model(object) | |
as = options[:as] | |
action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :patch] : [:new, :post] | |
options[:html].reverse_merge!( | |
:class => as ? "#{action}_#{as}" : dom_class(object, action), | |
:id => as ? "#{action}_#{as}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence, | |
:method => method | |
) | |
options[:url] ||= polymorphic_path(record, :format => options.delete(:format)) | |
end | |
private :apply_form_for_options! | |
end | |
module ActionDispatch::Routing::Mapper::Resources | |
class SingletonResource | |
def resource(*resources, &block) | |
options = resources.extract_options!.dup | |
if apply_common_behavior_for(:resource, resources, options, &block) | |
return self | |
end | |
resource_scope(:resource, SingletonResource.new(resources.pop, options)) do | |
yield if block_given? | |
collection do | |
post :create | |
end if parent_resource.actions.include?(:create) | |
new do | |
get :new | |
end if parent_resource.actions.include?(:new) | |
member do | |
get :edit if parent_resource.actions.include?(:edit) | |
get :show if parent_resource.actions.include?(:show) | |
if parent_resource.actions.include?(:update) | |
# all that for this PATCH | |
patch :update | |
put :update | |
end | |
delete :destroy if parent_resource.actions.include?(:destroy) | |
end | |
end | |
self | |
end | |
end | |
end | |
end |
require_dependency Rails.root.join("lib/patches/add_patch_method").to_s |
To help any others who come across this... in order to add this to your project:
- Create a file called 'add_patch_method.rb' in 'lib/patches' directory
- Paste the contents of the 'rails32_http_patch_support.rb' snippet above into the new 'add_patch_method.rb' file
- Create a file called 'rails32_http_patch_support_initializer.rb' in 'config/initializers' directory
- Paste contents of the 'rails32_http_patch_support_initializer.rb' snippet above into the new 'rails32_http_patch_support_initializer.rb' file
Hi,
It doesn't work with my app. Rails 3.2.22.5
It crashes when running
.rvm/gems/[email protected]/gems/actionpack-3.2.22.5/lib/action_dispatch/routing/mapper.rb:178:in `default_controller_and_action': missing :action (ArgumentError)
When running 'rake routes'
rake aborted!
ArgumentError: missing :action
/Users/danolee/.rvm/gems/[email protected]/gems/actionpack-3.2.22.5/lib/action_dispatch/routing/mapper.rb:178:in `default_controller_and_action'
Any help will be greatly appreciated.
UPDATE: It's not working. I forgot to restart webserver. :(
Never mind. I used the gist of @razum2um instead of the original one. This gist works just fine.
With the original gist, it crashes when running web server or 'rake routes'
ActionDispatch::Routing::Mapper::HttpHelpers
must be loaded beforeActiveSupport.on_load(:action_controller)
fixed version https://gist.github.com/razum2um/56a50c4ad73530a170ba
just put in into
config/initializers