2010-12-10 58 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