Объект модели Rails с областью имен без пути маршрута префикса модуля

У меня небольшая проблема с маршрутизатором Rails и генератором форм. В моем приложении есть модули с именами для моделей и контроллеров. Модуль используется для упрощения абстрагирования от других проектов.

Я использую метод области видимости routes.rb вместо пространства имен, потому что у меня не будет "уродливых" помощников пути.

Это выглядит как:

scope module: :taxonomy do
  resources :taxonomies do
    resources :terms
  end
end

Проблема в том, что когда я хочу отредактировать таксономию (url: taxonomies/1/edit), я получаю сообщение об ошибке:

undefined method `taxonomy_taxonomy_path'

потому что мой маршрут вместо этого только taxonomy_path

Есть ли способ, как достичь form_for @taxonomy, чтобы распознать, что маршрут ограничен? без использования form_for @taxonomy, url: taxonomy_path(@taxonomy), что не лечится. Поскольку объект @taxonomy в методах контроллера внутри respond_with @taxonomy всегда ссылается на taxonomy_taxonomy_url

мои модели:

module Taxonomy
  class Taxonomy < ActiveRecord::Base
    has_many :taxonomy_terms, inverse_of: :taxonomy
    has_many :terms, through: :taxonomy_terms
  class Term < ActiveRecord::Base
    has_one :taxonomy_term, inverse_of: :term
    has_one :taxonomy, through: :taxonomy_term

и контроллеры:

module Taxonomy
  class TaxonomiesController < ApplicationController

person rado    schedule 07.08.2012    source источник


Ответы (3)


Вы можете переопределить наименование модели ActiveRecord следующим образом:

module Taxonomy
  class Taxonomy < ActiveRecord::Base
    def self.model_name
      ActiveModel::Name.new("Taxonomy")
    end
  end
end

Это переопределяет генерацию имен ActiveRecord по умолчанию, которая генерирует имя taxonomy_taxonomy для класса таксономии, поскольку он находится в модуле таксономии. Это должно решить вашу проблему с именем маршрута и сгенерировать правильное имя маршрута, как вы хотите.

person Erez Rabih    schedule 07.08.2012
comment
У меня есть один вопрос по этому поводу. Решение с изменением имени модели вне пространства имен идеально, когда я не хочу обращаться к моделям без префикса пространства имен Таксономия::. Но есть ли проблемы, когда это должно быть критично, например, плохая изоляция моделей модулей, нестандартное поведение Rails или что-то в этом роде? - person rado; 07.08.2012
comment
Я не совсем понял ваш вопрос - вы имеете в виду, что теперь вы получаете доступ к таксономии класса по Taxonomy вместо Taxonomy::Taxonomy в своем коде? - person Erez Rabih; 07.08.2012
comment
Мой плохой, конечно, нет, он вызывает модуль, а не модель. Мой вопрос в том, что имя модели изменения не является контрпродуктивным, когда я хочу, чтобы только пути/URL-адреса маршрутов были без префикса. Например, будущие проблемы с обновлением Rails и т. д. - person rado; 07.08.2012
comment
Исправлен первый комментарий. Должен быть определен как ActiveModel::Name.new("Taxonomy::Taxonomy", nil, "Taxonomy") - person rado; 07.08.2012
comment
Какая у вас версия рельсов? - person Erez Rabih; 07.08.2012
comment
3.2.7 и когда мой проект все еще находится в разработке, я обновляюсь до последней версии. - person rado; 07.08.2012

Попробуйте это в route.rb:

namespace :taxonomy do
  resources :taxonomies do
    resources :terms
  end
end

Это, вероятно, потребует, чтобы вы также хранили свои контроллеры в подкаталоге с именем taxonomy.

person Thilo    schedule 07.08.2012
comment
Это работает, но путь с префиксом taxonomy_. Я использовал модуль области, чтобы иметь более красивые пути. - person rado; 07.08.2012

Я почти уверен, что вам нужно добавить модуль в свой класс из-за вашей структуры папок.

  app/models
  ├── ...
  ├── taxonomy
  │   ├── taxonomy.rb
  │   └── ...
  └── ...

Вы можете настроить rails для рекурсивной загрузки ваших моделей, расположенных во вложенных папках:

Настройте config/application.rb:

config.autoload_paths += Dir[ Rails.root.join('app', 'models', "taxonomy", '**/') ]

Вы можете установить эту конфигурацию для любой папки и подпапки в вашем приложении rails.


Если вы сделаете это, вам не придется переопределять модель ActiveRecord, что не всегда является лучшей идеей.

class Taxonomy < ActiveRecord::Base
  ...
end
person maguri    schedule 08.08.2018