Rails url_for and namespaced models

守給你的承諾、 提交于 2019-11-29 02:43:37

问题


In Rails, is it possible to namespace models in modules and still get correct behavior from url_for?

For instance, here, url_for works as expected:

# app/models/user.rb
class User < ActiveRecord::Base
end

# config/routes.rb
resources :users

# app/views/users/index.html.haml
= url_for(@user)    # /users/1

Whereas after putting the User model into a module, url_for complains about an undefined method m_user_path:

# app/models/m/user.rb
module M
  class User < ActiveRecord::Base
  end
end

# config/routes.rb
resources :users

# app/views/users/index.html.haml
= url_for(@user)    # undefined method 'm_users_path'

Is it possible to have url_for ignore the module in M::User and return user_path for url_for(@user) instead of m_user_path?

UPDATE

So, after almost 5 years, here's the solution, thanks to esad. This has been tested in Rails 4.2.

# app/models/m/user.rb
module M
  class User < ActiveRecord::Base
  end
end

# app/models/m.rb
module M
  def self.use_relative_model_naming?
    true
  end
  def self.table_name_prefix
    'm_'
  end
end

# config/routes.rb
resources :users

# app/views/users/index.html.haml
= url_for(@user)    # /users/1

Note: when generating model, view and controller with bin/rails g scaffold m/user, the views and the controller will be namespaced, too. You need to move app/views/m/users to app/views/users and app/controllers/m/users_controller.rb to app/controllers/users_controller.rb; you also need to remove references to the module M everywhere except in the model M::User.

Finally, the goal here was to namespace models but not views and controllers. With esads solution, the module M (containing User) is explicitly told to not appear in routes. Thus, effectifely, the M is stripped of and only User remains.

The user model can now reside in app/views/models/m/user.rb, the users controller lives in app/views/controllers/users_controller.rb and the views can be found in app/views/users.


回答1:


Just define use_relative_model_naming? in the containing module to avoid prefixing the generated route names:

module M
  def self.use_relative_model_naming?
    true
  end
end



回答2:


Use

namespace "blah" do
  resources :thing
end

Then routes will be named appropiately.

rake routes

To view all routes




回答3:


Specify the module on the route

resources :users, :module => "m"

or use scope to do it

scope :module => "m" do
  resources :users
end



回答4:


In my case I overridden the url_for method on my application_helper.rb file to add the :network param on all routes from my namespace :mkp.

module ApplicationHelper
  def url_for(options = {})
    if options.is_a?(Hash) && options.has_key?(:controller)
      if options[:network].nil? && options[:controller].match(/^mkp\//).present?
        options[:network] = @network.downcase
      end
    end
    super(options)
  end
end


来源:https://stackoverflow.com/questions/4404440/rails-url-for-and-namespaced-models

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!