如何避免Rails的脚手架将模型放入命名空间

33

Rails 3的脚手架生成器将模型类放置在命名空间内。 例如:

rails generate scaffold admin/portfolio

但我希望只有控制器和视图能够放置在 admin 命名空间中。

我该怎么避免这种情况?

8个回答

40

Rails 4 生成器有一些不同。如果使用 scaffold_controller 生成器,它将预先构建所有视图文件,但默认情况下它将查找名为 Admin::Portfolio 的模型。要加载正确的模型,只需将模型名称作为参数传递给生成器即可。

$ rails g model Portfolio
      invoke  active_record
      create    db/migrate/20150822164921_create_portfolios.rb
      create    app/models/portfolio.rb
      invoke    test_unit
      create      test/models/portfolio_test.rb
      create      test/fixtures/portfolios.yml

$ rails g scaffold_controller Admin::Portfolio --model-name=Portfolio
      create  app/controllers/admin/portfolios_controller.rb
      invoke  haml
      create    app/views/admin/portfolios
      create    app/views/admin/portfolios/index.html.haml
      create    app/views/admin/portfolios/edit.html.haml
      create    app/views/admin/portfolios/show.html.haml
      create    app/views/admin/portfolios/new.html.haml
      create    app/views/admin/portfolios/_form.html.haml
      invoke  test_unit
      create    test/controllers/admin/portfolios_controller_test.rb
      invoke  helper
      create    app/helpers/admin/portfolios_helper.rb
      invoke    test_unit
      invoke  jbuilder
      create    app/views/admin/portfolios
      create    app/views/admin/portfolios/index.json.jbuilder
      create    app/views/admin/portfolios/show.json.jbuilder
这将为您提供一个带有命名空间的控制器和视图,这些控制器和视图引用非命名空间模型。

谢谢mysmallidea,你是怎么发现--model-name选项的?这是需要查看源代码还是有文档可以参考的? - Quang Van
1
如果您键入 rails g scaffold_controller,它将显示该生成器的所有选项。 - Ryenski
1
rails g scaffold admin/portfolio 应用目录级命名空间 admin/,Ruby 命名空间为 Admin::Portfolio,并生成名为 admin_portfolio 的表,而上面的命令 (rails g scaffold Admin::Portfolio --model-name=Portfolio) 生成相同的目录和文件,但内容不同,因为模型没有以 admin_ 为前缀,尽管模型仍然被命名空间化为 Admin::Portfolio - aks
你的解决方案帮了我很多,谢谢! - Diego Somar
1
你可能需要在控制器中进行一些调整,例如将redirect_to @portfolio改为redirect_to [:admin, @portfolio] - phillyslick
您还需要在视图中使用命名空间更新路由和路径。 - Chakreshwar Sharma

24

rails generate model Portfolio

生成一个名为Portfolio的模型。

rails generate controller Admin::Portfolios

生成一个名为Admin::Portfolios的控制器。

1
在这种情况下,脚手架视图将如何生成? - Alexey Zakharov
1
当您生成控制器时,它也会创建视图。如果您将操作(例如index、show等)传递给生成控制器命令,则它将构建这些特定的视图并存根掉控制器操作。 - Jed Schneider
1
还可以使用scaffold_controller,它也将使用命名空间模型,但在这种情况下,无需修复模型命名空间。 - Alexey Zakharov
这将生成正确的控制器和模型文件,但这只是脚手架为您生成的一小部分。这可能是最好的方式(没有任何宝石),但这不再是脚手架。 - tybro0103
这个答案不应该被接受。因为它没有回答问题,只提供了一个平均的解决方案。 - scaryguy
1
生成脚手架视图,请参见我的回答 - Ryenski

7

@RubyDev建议使用Ryan Bate的Nifty Generators是正确的,但我不知道他为什么说要使用--skip-model选项。

Nifty Generators实际上会完全做你所要求的事情。只需将其添加到您的Gemfile中:

gem "nifty-generators"

并运行:

rails g nifty:scaffold Admin::Portfolio name:string

这将创建一个具有控制器和视图的常规脚手架,位于“admin”命名空间中,但模型不在命名空间中。

我的回答假设模型已经存在。但你是正确的,OP没有提到这一点! - Chandresh Pant

5

@tybro0103提供了更新内容

使用nifty:生成器:https://github.com/ryanb/nifty-generators

rails generate nifty:scaffold Admin::Portfolio

如果您已经生成了没有命名空间的模型或脚手架,并希望再次为管理员命名空间生成,请跳过模型:
rails generate nifty:scaffold Admin::Portfolio --skip-model

如果您希望脚手架使用所有字段生成视图,请再次输入字段名称,例如:
rails generate nifty:scaffold portfolio name:string
rails generate nifty:scaffold Admin::portfolio  name:string --skip-model

我通常会将它们一起执行,这样只需转到上一个命令并进行编辑以添加Admin::和--skip-model。


这就像是管理员页面制作的强大工具。 - lulalala

3
您现在可以使用以下命令在Rails上执行此操作(至少在5.1版本上可用):
rails g scaffold_controller admin/portfolio --model-name=Portfolio

通过指定 --model-name 选项,Rails 不会自动尝试猜测模型名称。

2
但是使用此选项生成的视图将使用错误的URL助手。使用模型的URL助手而不是admin_model的URL助手(例如:portfolios_path而不是admin_portifolios_path)。 - Jonas Porto
2
@JonasPorto 是的,你是对的,我手动更改了视图文件。 - haris
1
@vidurpunj 很不幸,是的。现在可能有更好的选择。我已经有一段时间没有使用Rails了。 - haris

3
你可以相当简单地创建自己的生成器并对其进行任何操作:
在Rails 4中:
#config/application.rb
config.generators do |g|
  g.scaffold_controller :my_controller
end

并且

#lib/generators/rails/my_controller/my_controller_generator.rb
class Rails::MyControllerGenerator < Rails::Generators::ScaffoldControllerGenerator
  def class_name
   ([file_name]).map!{ |m| m.camelize }.join('::')
  end

  def table_name
    @table_name ||= begin
      base = pluralize_table_names? ? plural_name : singular_name
      ([base]).join('_')
    end
  end
end

将模型命名空间去除。

请注意,如果您正在单独生成一个scaffold_controller,则需要显式调用自定义生成器:rails g my_controller 'account/users'

不幸的是,这只处理了控制器。我仍在寻找视图解决方案。


1
"Nifty generators曾经是正确的选择,但随着Rails 4的发布,它已经过时了。如果您想要生成非命名空间模型的管理脚手架,可以使用rails-admin-scaffold gem。"

0

最佳解决方案

rails generate scaffold admin/theme name:string active:integer position:integer --migration=false

rails generate migration CreateTheme name:string active:integer position:integer
# add t.timestamps in migration

因此它不会在表中生成前缀


1
这仍然将模型放在命名空间中。 - iconoclast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接