Rails url_for和命名空间模型

时间:2010-12-10 00:05:00

标签: ruby-on-rails ruby-on-rails-3 namespaces url-for

在Rails中,是否可以在模块中命名模型并仍然可以从url_for获得正确的行为?

例如,在这里,url_for按预期工作:

# 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

User模型放入模块后,url_for会抱怨未定义的方法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'

是否可以让url_for忽略M::User中的模块并返回user_path代替url_for(@user)而不是m_user_path

更新

所以,差不多5年后,这是解决方案,感谢esad。这已经在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

注意:使用bin/rails g scaffold m/user生成模型,视图和控制器时,视图和控制器也将被命名空间。您需要将app/views/m/users移至app/views/usersapp/controllers/m/users_controller.rb移至app/controllers/users_controller.rb;除模型M外,您还需要删除模块M::User的引用。

最后,这里的目标是命名空间模型,但不是视图和控制器。使用esads解决方案,模块M(包含User)被明确告知不会出现在路由中。因此,有效地,M被删除,只留下User

用户模型现在可以驻留在app/views/models/m/user.rb中,用户控制器位于app/views/controllers/users_controller.rb中,并且可以在app/views/users中找到视图。

4 个答案:

答案 0 :(得分:24)

只需在包含模块中定义use_relative_model_naming?,以避免为生成的路径名添加前缀:

module M
  def self.use_relative_model_naming?
    true
  end
end

答案 1 :(得分:4)

使用

namespace "blah" do
  resources :thing
end

然后路线将被恰当地命名。

rake routes

查看所有路线

答案 2 :(得分:3)

指定路线上的模块

resources :users, :module => "m"

或使用范围来做到这一点

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

答案 3 :(得分:0)

在我的情况下,我覆盖了application_helper.rb文件中的url_for方法,在我的命名空间的所有路径上添加:network param: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