2010-12-10 146 views
13

在Rails中,是否可以在模块中命名空间模型,并仍然从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

UPDATE

于是,经过近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::User以外,您还需要删除对模块M的引用。

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

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

回答

23

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

module M 
    def self.use_relative_model_naming? 
    true 
    end 
end 
4

使用

namespace "blah" do 
    resources :thing 
end 

然后路线将appropiately命名。

rake routes 

要查看所有路由

+0

谢谢,我试过了,但它并没有解决问题:虽然url_for获取有关模型命名空间通知,路由(控制器)将适应于使用相同的命名空间 - 这不是我所需要的。 因此:是否可以设置路线以使用不同名称空间中的模型和控制器?换句话说,是否有一种方法可以影响url_for给定模型实例的行为,而不触及控制器路由? 例如,模型M :: User将在app/models/m/user.rb中定义,而控制器将在app/controllers/user_controller.rb中定义。 – sebastian 2010-12-12 18:31:45

+0

另外,如果它不是RESTFul资源,你会怎么做?我有这个问题,我正在处理的控制器不能成为一个资源。 – Ibrahim 2010-12-24 03:39:47

+0

资源:事情做(新行)得到“foo”=>“控制器#行动”。 – sethvargo 2010-12-25 17:06:01

3

指定模块的路由

resources :users, :module => "m" 

或使用范围做

scope :module => "m" do 
    resources :users 
end 
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