Suddenly getting 405 errors when using patch or put methods

I am working in a simple test application with Paperclip, and while I am able to upload in a #create, I am getting 405 errors from Webrick and Thin (in development) when trying to use the #update method.

I don't even get to the point in my console where I see the params -- it's happening before that. It's not a Rails error message, it's coming directly from the server.

I started in 4.2.1 and Ruby 2.1.3, and I have tried the entire matrix of 4.2.0 and 2.1.2 also without any change. I also tried both Chrome and Safari without any difference. I'm using Mac OS X 10.9.5 and rvm, if that makes any difference.

Thanks,

Walter

Assuming you run webrick in a terminal, what do you see in that
terminal when you submit the request?

Colin

Started PATCH "/assets/1" for ::1 at 2015-05-02 15:32:49 -0400

The browser shows plain text:

Method Not Allowed

and nothing else. It never hits ActiveRecord or even ActionController, as best I can see.

I can go back and reload and see the form page (and that is nothing remarkable -- I made it with the scaffold). I can view the index and use #create to make another such, but if I try to edit it, I get the error.

Walter

Have you got a model called Asset? I suspect that might cause
confusion with assets (js, css etc).
Is it only with assets that you get the problem?

Colin

I'll try renaming it, but I have used this pattern (and names) on many applications (this test app is an extraction from a working commercial application of mine, although that uses 4.1.8) and I am just trying to stub out multiple file uploads in this exercise.

I just re-built my environment -- re-installed rvm, ruby 2.1.3, bundler, rake, rails 4.2.1, and dropped a couple of gems that looked suspicious -- and started completely over with scaffold again. I am getting the identical problem.

If it's just the name of the model, I will be frankly surprised, because each revision of Rails seems to remove reserved words, not add new ones.

While I do that, here's the actual code -- if you can see anything suspicious, I'd be very grateful.

class Asset < ActiveRecord::Base
  belongs_to :project
  has_attached_file :blob, :styles => { :large => "800x800", :medium => "400x400>", :small => "200x200>"}
  do_not_validate_attachment_file_type :blob
end

class Project < ActiveRecord::Base
  has_many :assets
  accepts_nested_attributes_for :assets, reject_if: :all_blank, allow_destroy: true
end

Rails.application.routes.draw do
  resources :projects
  resources :assets
end

The pattern I am trying to solve for is upload multiple assets in the project form (this works perfectly) and edit individual uploaded assets in their own assets/edit form. This latter part does not work.

This is the form that is failing:

<%= form_for(@asset) do |f| %>
  <% if @asset.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@asset.errors.count, "error") %> prohibited this asset from being saved:</h2>

      <ul>
      <% @asset.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :project_id %>
    <%= f.text_field :project_id %>
  </div>
  <div class="field">
    <%= f.label :blob %>
    <%= f.file_field :blob %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

While this one works just fine:

<%= form_for(@project) do |f| %>
  <% if @project.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@project.errors.count, "error") %> prohibited this project from being saved:</h2>

      <ul>
      <% @project.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name %>
  </div>
  <%= f.fields_for :assets do |a| %>
  <div class="field">
    <%= a.label :blob %>
    <%= a.file_field :blob, multiple: true, name: "project[assets_attributes][][blob]" %>
  </div>
  <%- end -%>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Walter

Thanks, Colin, for being able to state the obvious. Changing the model name made all the difference. Good to know, because I was starting to have some trust issues here...

Walter

I think the reason is that assets are served directly by the web
server, hence the request did not get to rails at all.

Colin

If it's just the name of the model, I will be frankly surprised, because each revision of Rails seems to remove reserved words, not add new ones.

Thanks, Colin, for being able to state the obvious. Changing the model name made all the difference. Good to know, because I was starting to have some trust issues here...

I think the reason is that assets are served directly by the web
server, hence the request did not get to rails at all.

That doesn't jibe with what I am seeing in the rest of the application. I can GET them, and they go all the way through Rails, I can index them, and I can POST to the collection and create a new asset. It's just PATCH and PUT on the individual asset object that are affected.

I agree that changing the name is the expedient fix (although it's going to be hard to find another "neutral" name for "sub-project element that might be an image or a Flash banner ad or H264 movie"). I guess I'll call them Element, unless you have another suggestion.

Thanks again for your help,

Walter

Have you tried this running Thin in `trace` or `debug` mode? That
might be enlightening.

A simple test case to repro would be helpful, too.

I filed a bug report on rails/rails, and several people chipped in to help me locate the solution. Sprockets 3 is simultaneously greedy about the /assets route and silent about that fact. Adding this config statement:

Rails.application.config.assets.prefix = '/the-other-assets'

lets you get on with life when your model is named Asset.

Walter