我有一个名为Book的Active Record模型和一个名为Book::Author的模型.作者通过Book::Authorship模型(一对多关联)拥有许多书籍.

离题:

将Author模型置于Book命名空间下的原因是,我可能希望拥有另一个与Book::Author完全无关的作者模型(例如Post::Author).通过命名空间,我可以清楚地显示关系,例如:example.com/books/authors明确指出这些是写书的作者(而不是帖子或其他任何东西).

在我的应用程序中,只有管理员可以创建/更新/删除书籍和作者.因此,我为控制器和仅为管理员创建了一个单独的命名空间Admin.

routes.rb文件中我有:

Rails.application.routes.draw do
  # These are for the regular users:
  # only #index and #show actions are defined in the respective controllers:
  namespace :books do
    resources :authors, only: %i[index show]
  end
  resources :books, only: %i[index show]

  # These are for the admins only:
  # all CRUD methods are defined in the respective controllers:
  namespace :admin do
    namespace :books do
      resources :authors
    end

    resources :books
  end
  resources :admin

  root "books#index"
end

然后我创建了Admin::Books::AuthorsController控制器:

  • /app/controllers/admin/books/authors_controller.rb

I would expect that the view path follows the same path pattern:

  • 指数为/app/views/admin/books/authors/_index.html.erb;
  • 部分/app/views/admin/books/authors/_author.html.erb.

Unfortunately, it doesn't:索引页面确实可以工作,但找不到_author.html.erb部分.

以下是我试图呈现/app/views/admin/books/authors/_index.html.erb位作者列表的方式:

  <% @books_authors.each do |book_author| %>
    <%= render book_author %>
  <% end %>

Which gives the following error:

ActionView::MissingTemplate in Admin::Books::Authors#index

缺少部分管理/books/books/作者/_作者和{.}.

There are two “books” in the path...但为什么?

works only with an explicit path to the template以上的代码:

  <% @books_authors.each do |book_author| %>
    <%= render "admin/books/authors/author", book_author: book_author %>
  <% end %>

我不喜欢这,因为它打破了配置范式的惯例.我不想在Admin::Books::命名空间下的每个视图中手动输入路径.

I'm looking for a way to achieve the desired functionality without using an explicit path.当Rails寻找部分内容时,我如何告诉它不要在路径中包含两次"书籍"?

推荐答案

您的控制器命名空间为Admin::Books,您的模型命名空间为Books::Author,合在一起您就会得到双"books"路径.逻辑大致为looks,如下所示:

[
  File.dirname(Admin::Books::AuthorsController.new.lookup_context.prefixes.first),
  Books::Author.new.to_partial_path
].join("/")

#=> "admin/books/books/authors/author"

lookup_context是您可以修改的内容(可能不是一个好主意):

# app/controllers/admin/books/authors_controller.rb

def index
  lookup_context.prefixes = ["admin/books", "application"]
  @books_authors = Books::Author.all
end

另一种方法是删除Books个命名空间之一:

# either change your controller
class Admin::AuthorsController < ApplicationController
  def index
    @books_authors = Books::Author.all
  end
end

# or model, what if someone writes a book and a post?
class Admin::Books::AuthorsController < ApplicationController
  def index
    @books_authors = Author.joins(:books)
  end
end

保持模型平坦是遵守惯例、没有名称空间的流行方法-没有问题:

BookAuthor
PostAuthor

Ruby-on-rails相关问答推荐

Rails:has_many 通过不返回结果

您如何测试方法调用块内调用的方法,以及使用 rspec 在块内传递给该方法调用的内容

ViewModel 和 Controller 有什么区别?

ArgumentError:您需要使用 :if 提供至少一个验证

Rails 发现获取 ActiveRecord::RecordNotFound

使用回形针进行简单裁剪

耙路由错误缺少:路由定义上的操作键

用 url_for 查询参数?

渲染:动作和渲染:模板之间的区别

是否可以在 Rails 中否定范围?

Rails(或 Ruby):Yes/No 而不是 True/False

如何为rails中的number_field添加默认值?

Django 还是 Ruby-On-Rails?

有没有办法列出所有 belongs_to 关联?

如何仅使用 PostgreSQL 创建简单的模糊搜索?

Rspec - Rails - 如何遵循重定向

Vagrant上的Rails 4.2服务器端口转发不起作用

设计:为什么我的注销链接不起作用?

Ruby on Rails:如何在 select_tag 中使用默认占位符?

Ruby 中的类别名