-
-
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 |
ActionDispatch::Routing::Mapper::HttpHelpers
must be loaded before ActiveSupport.on_load(:action_controller)
fixed version https://gist.github.com/razum2um/56a50c4ad73530a170ba
just put in into config/initializers
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'
help. glad to have found this but doesnt work as expected. I was hoping using this would make my existing "resources" routes work with patch, but I still get the error.
Do I need to change my routes?