Rails 4 Devise, Pundit, Join Table ActionView::Template::Error (неопределенный метод `task_definition_path' для #‹#‹Class:0x37682f95›:0x6919b2b2›):

Вот мой вариант использования:

  1. У меня есть одна пользовательская модель с Devise для AuthN, и я использую Pundit для AuthZ.
  2. Я ограничиваю доступ к основному приложению через ограничение поддомена.
  3. У меня есть несколько страниц для конечных пользователей (в какой-то момент это будет другой LandF), а также административные страницы и т. д. Обычная история, суть которой вы знаете.
  4. Я использую has_and_belongs_to_many, используя таблицу соединений с: id
  5. У меня есть мои контроллеры, каталоги просмотра и миграции, названные во множественном числе, мои модели - в единственном числе. Пример: TaskDefinition => Модель, TaskDefinitions => Контроллер и Таблицы.
  6. Маршруты по умолчанию сгенерированы, и я предоставил контент.
  7. Я использую частичные файлы в каталогах просмотра, и это очень новая проблема с момента переноса с Ruby на JRuby.

Трассировки стека:

ActionView::Template::Error (undefined method `task_definition_path' for #<#<Class:0x37682f95>:0x6919b2b2>):
    10:     <div class="col-md-10">
    11:       <div class="panel-body">
    12:         <div class="form">
    13:           <%= bootstrap_form_for @task do |f| %>
    14:               <div class="form-group">
    15:                 <%= render '/admin/task_definitions/errors' %>
    16:               </div>
  app/views/admin/task_definitions/edit.html.erb:13:in`_app_views_admin_task_definitions_edit_html_erb__1276994696_33458'

Миграции:

class CreateTaskDefinitions < ActiveRecord::Migration
  def change
    create_table :task_definitions do |t|
      # foreign key
      t.integer :organization_id

      # attributes
....

      t.timestamps
    end

    # index
    add_index :task_definitions, :name, unique: true
  end
end

class CreateOrganizations < ActiveRecord::Migration
  def change
    create_table :organizations do |t|
      # for the relationship between parent orgs and child nodes
      t.references :parent

      # Used to determine Parent or Child
      t.string :org_type

      # Subdomain used for scoping site
      t.string :subdomain

      # Common fields
....

      t.timestamps
    end
    # index
    add_index :organizations, [:name, :subdomain], unique: true
  end
end

class CreateOrganizationsTaskDefinitions < ActiveRecord::Migration
  def change
    create_table :organizations_task_definitions, id: false do |t|
      t.integer :organization_id
      t.integer :task_definition_id
    end
    add_index :organizations_task_definitions, [:organization_id, :task_definition_id], name: 'index_organizations_task_definitions'
  end
end

модели:

class Organization < ActiveRecord::Base
  #associations
  has_many :users, class_name: 'User', inverse_of: :organization
  has_and_belongs_to_many :task_definitions, class_name: 'TaskDefinition', inverse_of: :organizations
  has_one :address, class_name: 'Address'
  has_many :children, class_name: 'Organization', foreign_key: 'parent_id'
  belongs_to :parent, class_name: 'Organization'
  accepts_nested_attributes_for :address
end

class TaskDefinition < ActiveRecord::Base
  #associations
  has_many :steps, class_name: 'TaskStep', inverse_of: :task_definition
  has_and_belongs_to_many :organizations, class_name: 'Organization', inverse_of: :task_definitions
  has_and_belongs_to_many :task_events, class_name: 'TaskEvent', inverse_of: :task_definitions
  accepts_nested_attributes_for :steps
end

Контроллер:

class Admin::TaskDefinitionsController < ApplicationController
  before_filter :authenticate_user!
  after_action :verify_authorized

.....

  def edit
    @tasks = current_organization.task_definitions
    if(@tasks.size > 0 )
      @task = @tasks.find(params[:id])
      authorize @task

      # add breadcrumb
      add_breadcrumb @task.name, admin_task_definition_path(@task)

      unless current_user.org_super_admin? or current_user.finch_admin?
        unless @user == current_user
          redirect_to :back, :alert => "Access denied."
        end
      end
    end
  end
end

Маршруты:

Rails.application.routes.draw do
 ......

  constraints(Finch::Constraints::SubdomainRequired) do
    #
    # dashboards
    #
    resource :dash_boards, only: [:index, :show, :edit, :update, :destroy]

    #
    # orgss
    #
    resource :organizations, only: [:index, :show, :edit, :update, :destroy]

    #
    # Only Admins are allowed to access
    #
    namespace :admin do
      #
      # Workflow Data
      #
      resources :task_definitions, only: [:index, :show, :edit, :update, :destroy]
      resources :task_steps, only: [:show, :edit, :update, :destroy]
      resource  :task_actions, only: [:show, :edit, :update, :destroy]
      resource  :task_action_attributes, only: [:show, :edit, :update, :destroy]
      resource  :task_transitions, only: [:show, :edit, :update, :destroy]
    end
  end
end

Посмотреть:

    <div class="form">
      <%= bootstrap_form_for @task do |f| %>
          <div class="form-group">
            <%= render '/admin/task_definitions/errors' %>
          </div>

рейк маршруты:

           edit_organizations GET    /organizations/edit(.:format)                organizations#edit
                organizations GET    /organizations(.:format)                     organizations#show
                              PATCH  /organizations(.:format)                     organizations#update
                              PUT    /organizations(.:format)                     organizations#update
                              DELETE /organizations(.:format)                     organizations#destroy
       admin_task_definitions GET    /admin/task_definitions(.:format)            admin/task_definitions#index
   edit_admin_task_definition GET    /admin/task_definitions/:id/edit(.:format)   admin/task_definitions#edit
        admin_task_definition GET    /admin/task_definitions/:id(.:format)        admin/task_definitions#show

person Carson City    schedule 12.10.2014    source источник


Ответы (1)


Ошибки неопределенного метода, оканчивающиеся на _path или _url, обычно указывают на неверный помощник маршрута.

Проверяя место ошибки, кажется, что вспомогательный метод (bootstrap_form_for) вызывает помощник маршрута task_definitions_path, что неверно. Этот маршрут находится в пространстве имен под admin в соответствии с вашим файлом маршрутов, поэтому правильный помощник маршрута:

admin_task_definitions_path  

Я не знаю, что находится во вспомогательном методе bootstrap_form_for, поэтому у меня нет конкретного решения для вас. Предполагая, что вы используете гем форм Bootstrap, пропустите его и напишите форму вручную.


В будущем rake routes будет показывать все зарегистрированные хелперы маршрутов. Удобный список для отладки хелперов плохих маршрутов.

person Substantial    schedule 12.10.2014
comment
Спасибо за помощь. У меня тоже была эта мысль, и я изменил bootstrap_form_for и попробовал его с form_for, который возвращает тот же результат. Я довольно часто использую команду rake route, и я согласен, что ошибка заключается в каком-то компоненте, использующем task_definition_path, но фактический маршрут — admin_task_definiton_path. Я попытался явно объявить get в маршрутизации, но он загружается и находит объект просто отлично. Я на самом деле нахожу контроллер и метод в контроллере из вызывающего представления. Я использовал это экстенсивно, и я не вижу исправление для этой ошибки. - person Carson City; 13.10.2014
comment
Проблема была с пространством имен администратора, которое я до сих пор не понял, почему. Если я удалю пространство имен, все будет работать нормально. Если я добавлю его обратно, это будет бомба. Маршруты показывают правильные маршруты, но ему не нравится пространство имен в файле маршрутов. - person Carson City; 14.10.2014