2010-12-10 3 views
13

В Rails, возможно ли использовать модели пространства имен в модулях и по-прежнему получать правильное поведение от url_for?Rails url_for и namespaced модели

Например, здесь, 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/users и app/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.

ответ

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_ для данного экземпляра модели, не касаясь маршрутов контроллера? Например, модель M :: User будет определена в приложении/models/m/user.rb, тогда как контроллер будет определен в app/controller/user_controller.rb. – sebastian 2010-12-12 18:31:45

+0

Также, что вы делаете, если это не ресурс RESTFul? У меня есть эта проблема, и контроллер, с которым я имею дело, не может быть привязан к ресурсу. – Ibrahim 2010-12-24 03:39:47

+0

Ресурсы: вещи делают (новая строка) получают «foo» => «controller # action». – sethvargo 2010-12-25 17:06:01

3

Укажите модуль на маршруте

resources :users, :module => "m" 

или использовать область, чтобы сделать это

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

В моем случае я переопределил метод url_for в файле application_helper.rb, чтобы добавить: 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 
Смежные вопросы