0

I keep getting an error saying uninitialized constant Page::PageAttachment when trying to create a nested form using the nested_form gem. Here is some relevant code. Let me know if you need any other code or have any questions.

Stacktrace isn't really telling me anything except that the failing line is this one: <%= f.fields_for :page_attachments, wrapper: false do |a| %>

# /config/routes.rb
namespace "wiki" do
  resources :spaces do
    resources :pages
  end
end

# /app/models/wiki/space.rb
module Wiki
  class Space < ActiveRecord::Base
    has_many :pages, dependent: :destroy

    validates_presence_of :name
  end
end

# /app/models/wiki/page.rb
module Wiki
  class Page < ActiveRecord::Base
    belongs_to :space
    has_many :page_attachments, dependent: :destroy

    validates_presence_of :name

    accepts_nested_attributes_for :page_attachments, :allow_destroy => true
  end
end


# /app/models/wiki/page_attachment.rb
module Wiki
  class PageAttachment < ActiveRecord::Base
    belongs_to :page
  end
end

# /app/controllers/wiki/pages_controller.rb
class Wiki::PagesController < WikiController
  def new
    @space = Wiki::Space.find(params[:space_id])
    @page = Wiki::Page.new
  end
end

# /app/views/wiki/new.html.erb
<% provide(:title, 'Create a Page') %>

<%= nested_form_for @page, url: wiki_space_pages_path(@space.id), html: { role: "form", multipart: true } do |f| %>
  <%= render "shared/error_messages", obj: @page %>
  <fieldset>
    ... a bunch of form fields ...
  </fieldset>
  <fieldset>
    <legend>Page Attachments</legend>
    <%= f.fields_for :page_attachments, wrapper: false do |a| %>
      <div class="form-group fields">
        <%= a.label :file, "File", class: "sr-only" %>
        <%= a.file_field :file, class: "form-control" %> <%= a.link_to_remove "Remove", class: "button button-danger" %>
      </div>
    <% end %>
    <p><%= f.link_to_add "+ Add Attachment", :page_attachments %></p>
  </fieldset>
  <div class="form-actions">
    <%= f.hidden_field :space_id, value: @space.id %>
    <%= f.submit "Create Page", class: "button button-primary" %>
    <%= link_to "Cancel", :back, class: "text-button" %>
  </div>
<% end %>

Update

My folder structure is as follows:

app
    controllers
        wiki
            pages_controller.rb
    models
        wiki
            page.rb
            page_attachment.rb
    views
        wiki
            pages
                new.html.erb
                show.html.erb
                ... etc ...
ryanpitts1
  • 690
  • 1
  • 13
  • 31

2 Answers2

2

Rails is not able to find PageAttachment model so it's looking for the second best option, Page::PageAttachment which obviously is not there.

Rails conventions say that models inside subfolders should be namespaced accordingly. With your folder structure, Rails expects the models to be Wiki::Page and so forth. I believe that was an error cause in the past, maybe it's not for your Rails version.

Namespace your models and controllers inside wiki folders with Wiki module like this:

# /app/models/wiki/page.rb
module Wiki
  class Page < ActiveRecord::Base
  end
end

And then use them with the full class name all along the code:

class Wiki::PagesController < WikiController
  def new
    @space = Wiki::Space.find(params[:space_id])
    @page  = Wiki::Page.new
  end
end

You can also move those models to their respective root folders, unnamespaced, but that depends on your app design.

dgilperez
  • 9,981
  • 8
  • 60
  • 89
  • Ok, if i understood you correctly, i have made the edits to the files and updated my question to reflect them. I am now getting the same error but is now says `uninitialized constant Wiki::Page::PageAttachment`. Looks like it still can't find PageAtachment. Do i need to do anything with the `config/routes.rb` file or the `url: wiki_space_pages_path(@space.id)` that i am passing the nested form? Or possibly update the `belongs_to` and `has_many` declarations? – ryanpitts1 Feb 10 '15 at 20:50
  • Also tried moving all of the models straight into the `models` directory, removed the `module` lines from the models, and removed all `Wiki::` from the references to the models. I still get the `uninitialized constant Page::PageAttachment ` error. – ryanpitts1 Feb 10 '15 at 21:11
  • Ok, you can read my answer below but apparently it was a line inside of the `PageAttachment` model that was causing the error. Didn't add that line to my example above because the error message wasn't keying me in that direction. I thought the model was just not being found in general - not that there was an error inside the model. – ryanpitts1 Feb 10 '15 at 21:55
  • Oh. I'm glad you sorted it out! – dgilperez Feb 11 '15 at 10:37
0

Well, rails just wasn't telling me how deep the error was i guess. In the PageAttachment model file i had this line mount_uploader :file, FileUploader of which i am using Carrierwave to handle file uploads. The actual uploader class name was WikiUploader.

As soon as i fixed the naming to match up with each other, the uninitialized constant Page::PageAttachment error went away and the page loaded fine. Weird. Still not sure why it was complaining about PageAttachment when it was really the uploader's fault. In any case, it's fixed now and in the process i decided against namespacing my models. The controllers i will still keep namespaced but not the models.

ryanpitts1
  • 690
  • 1
  • 13
  • 31