Rails 中使用嵌套形式的未初始化常量
Uninitialized constant using nested forms in Rails
在尝试使用 nested_form
gem 创建嵌套表单时,我一直收到错误提示 uninitialized constant Page::PageAttachment
。这是一些相关的代码。如果您需要任何其他代码或有任何疑问,请告诉我。
Stacktrace 并没有真正告诉我任何事情,除了失败的那一行:<%= 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 %>
更新
我的文件夹结构如下:
app
controllers
wiki
pages_controller.rb
models
wiki
page.rb
page_attachment.rb
views
wiki
pages
new.html.erb
show.html.erb
... etc ...
Rails 无法找到 PageAttachment
模型,因此它正在寻找第二个最佳选项,Page::PageAttachment
显然不存在。
Rails 约定说子文件夹中的模型应该相应地命名。使用您的文件夹结构,Rails 期望模型为 Wiki::Page
等等。我认为这是过去的一个错误原因,也许它不适用于您的 Rails 版本。
使用 Wiki
模块在 wiki
文件夹中命名您的模型和控制器,如下所示:
# /app/models/wiki/page.rb
module Wiki
class Page < ActiveRecord::Base
end
end
然后在整个代码中使用完整的 class 名称:
class Wiki::PagesController < WikiController
def new
@space = Wiki::Space.find(params[:space_id])
@page = Wiki::Page.new
end
end
您也可以将这些模型移动到它们各自的根文件夹中,不带命名空间,但这取决于您的应用程序设计。
好吧,rails 只是没有告诉我我猜错误有多严重。在 PageAttachment
模型文件中,我有这一行 mount_uploader :file, FileUploader
,其中我使用 Carrierwave 来处理文件上传。实际上传者 class 姓名为 WikiUploader
。
一旦我修复了彼此匹配的命名,uninitialized constant Page::PageAttachment
错误就消失了,页面加载正常。诡异的。仍然不确定为什么它在抱怨 PageAttachment
时确实是上传者的错。无论如何,它现在已经修复了,在这个过程中我决定不给我的模型命名空间。控制器我仍然会保留命名空间,但不会保留模型。
在尝试使用 nested_form
gem 创建嵌套表单时,我一直收到错误提示 uninitialized constant Page::PageAttachment
。这是一些相关的代码。如果您需要任何其他代码或有任何疑问,请告诉我。
Stacktrace 并没有真正告诉我任何事情,除了失败的那一行:<%= 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 %>
更新
我的文件夹结构如下:
app
controllers
wiki
pages_controller.rb
models
wiki
page.rb
page_attachment.rb
views
wiki
pages
new.html.erb
show.html.erb
... etc ...
Rails 无法找到 PageAttachment
模型,因此它正在寻找第二个最佳选项,Page::PageAttachment
显然不存在。
Rails 约定说子文件夹中的模型应该相应地命名。使用您的文件夹结构,Rails 期望模型为 Wiki::Page
等等。我认为这是过去的一个错误原因,也许它不适用于您的 Rails 版本。
使用 Wiki
模块在 wiki
文件夹中命名您的模型和控制器,如下所示:
# /app/models/wiki/page.rb
module Wiki
class Page < ActiveRecord::Base
end
end
然后在整个代码中使用完整的 class 名称:
class Wiki::PagesController < WikiController
def new
@space = Wiki::Space.find(params[:space_id])
@page = Wiki::Page.new
end
end
您也可以将这些模型移动到它们各自的根文件夹中,不带命名空间,但这取决于您的应用程序设计。
好吧,rails 只是没有告诉我我猜错误有多严重。在 PageAttachment
模型文件中,我有这一行 mount_uploader :file, FileUploader
,其中我使用 Carrierwave 来处理文件上传。实际上传者 class 姓名为 WikiUploader
。
一旦我修复了彼此匹配的命名,uninitialized constant Page::PageAttachment
错误就消失了,页面加载正常。诡异的。仍然不确定为什么它在抱怨 PageAttachment
时确实是上传者的错。无论如何,它现在已经修复了,在这个过程中我决定不给我的模型命名空间。控制器我仍然会保留命名空间,但不会保留模型。