32

Rails 3 scaffold generator places model classes inside namespace. Example:

rails generate scaffold admin/portfolio

But I want only controllers and views to be placed inside admin namespace.

How can I avoid that?

notapatch
  • 6,569
  • 6
  • 41
  • 45
Alexey Zakharov
  • 24,694
  • 42
  • 126
  • 197

8 Answers8

40

Rails 4 generators are a bit different. If you use the scaffold_controller generator it will pre-build all the view files, but by default it will look for a model called Admin::Portfolio. To load the correct model just pass the model name as an argument to the generator.

$ 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

This will give you a namespaced controller and views that reference the non-namespaced model.

Ryenski
  • 9,582
  • 3
  • 43
  • 47
  • Thanks mysmallidea, how did you find out about the --model-name option? Is that something you need to look at the source code for, or is there docs somewhere? – Quang Van Jan 07 '16 at 21:20
  • 1
    If you type `rails g scaffold_controller` it will show you all the options for that generator. – Ryenski Jan 08 '16 at 00:13
  • 1
    `rails g scaffold admin/portfolio` applies a directory-level namespace `admin/`, a Ruby namespace of `Admin::Portfolio`, and a table named `admin_portfolio`, whereas the command above (`rails g scaffold Admin::Portfolio --model-name=Portfolio`) generates the same directories and files, but the content is different in that the models are not prefixed with `admin_`, even though the model is still namespaced as `Admin::Portfolio`. – aks Jan 15 '16 at 00:35
  • Your solution helped me a lot. Thanks! – Diego Somar Feb 23 '17 at 16:04
  • 1
    You may have to adjust a few things in the controller, such as: ```redirect_to @portfolio``` to ```redirect_to [:admin, @portfolio]``` – phillyslick May 23 '17 at 16:33
  • You also need to update the routes and paths in views with the namespace – Chakreshwar Sharma Mar 15 '20 at 08:54
23

rails generate model Portfolio

rails generate controller Admin::Portfolios

Jed Schneider
  • 14,085
  • 4
  • 35
  • 46
  • 1
    How scaffold view would be generated in this case? – Alexey Zakharov Sep 27 '10 at 04:07
  • 1
    when you generate the controller, it creates the views as well. if you pass actions, eg (index, show, etc) to the generate controller command, it will build those specific views and stub out the controller actions. – Jed Schneider Sep 27 '10 at 15:57
  • 1
    It is also possible to use scaffold_controller that will also use namespaced model, but in this case there is no need to fix model namespace. – Alexey Zakharov Sep 30 '10 at 14:50
  • This will generate the correct controller and model files, but that's just a fraction of what scaffold generates for you. It's probably the best means to the end (sans any gems), but it's no longer scaffolding. – tybro0103 Jul 11 '12 at 23:52
  • This answer should not be accepted. Because the answer is not answering the question but providing an average solution. – scaryguy Jan 11 '15 at 01:05
  • 1
    To generate scaffold views, see [my answer below](http://stackoverflow.com/questions/3786933/how-to-avoid-rails-scaffold-to-place-model-into-namespace/32158575#32158575). – Ryenski Nov 02 '15 at 16:28
7

@RubyDev was right to suggest Ryan Bate's Nifty Generators, but I don't know why he said to use the --skip-model option.

Nifty Generators will actually do exactly what you are asking for. Simply add it to your Gemfile:

gem "nifty-generators"

and run:

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

This will create everything a normal scaffold would with the controllers and views in an 'admin' namespace, but the model not in namespace.

tybro0103
  • 48,327
  • 33
  • 144
  • 170
5

Updated as per @tybro0103

Use nifty:generators: https://github.com/ryanb/nifty-generators

rails generate nifty:scaffold Admin::Portfolio

If you have already generated the model or scaffold without namespace and would like to do it again for admin namespace, you can skip model:

rails generate nifty:scaffold Admin::Portfolio --skip-model

If you would like the scaffold to generate views with all fields, please put the field names again, e.g:

rails generate nifty:scaffold portfolio name:string
rails generate nifty:scaffold Admin::portfolio  name:string --skip-model

I usually do the two together so its easy to just go to previous command and edit it to add Admin:: & --skip-model.

Chandresh Pant
  • 1,173
  • 15
  • 19
3

You can fairly simply create your own generators and do whatever you want with them:

In Rails 4:

#config/application.rb
config.generators do |g|
  g.scaffold_controller :my_controller
end

and

#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

Will remove the model namespacing.

Bear in mind if you are generating a scaffold_controller on its own you'll need to explicitly call your custom generator: rails g my_controller 'account/users'

Unfortunately this only handles the controller. I'm still searching for a view solution.

Paul Odeon
  • 4,407
  • 1
  • 37
  • 37
3

You can do this now on Rails (or at least on 5.1) using the following command:

rails g scaffold_controller admin/portfolio --model-name=Portfolio

By specifying --model-name Rails does not automatically tries to guess the model name.

haris
  • 3,775
  • 1
  • 25
  • 28
  • 2
    But with this option the generated views will use the wrong url helpers. using model's url helper instead of admin_model's url helpers (eg.: `portfolios_path` instead of `admin_portifolios_path`) – Jonas Porto Feb 17 '18 at 20:52
  • 2
    @JonasPorto Yep, you're right, I manually change the view files. – haris Feb 18 '18 at 03:39
  • 1
    @vidurpunj Unfortunately yes. There might be a better option now. I haven't used Rails in a while now. – haris Jul 18 '20 at 13:36
1

Nifty generators was the right thing some time ago, but now as Rails 4 released it became outdated. If you want to generate admin scaffolding with non-namespaced model you can use rails-admin-scaffold gem.

dhampik
  • 144
  • 2
  • 4
0

The best solution

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

So it does not generate a prefix in the tables

gilcierweb
  • 2,598
  • 1
  • 16
  • 15