Ошибка маршрутизации для модели с join_table и has_many :through в RailsAdmin

Итак, у меня есть 3 модели: category, product, category_products.

Это мой category.rb

  attr_accessible :name
    has_many :category_products do
         def with_products
           includes(:product)
         end
       end

  has_many :products, :through => :category_products

Это мой product.rb

  attr_accessible :name, :description, :price, :vendor_id, :image, :category_ids

    belongs_to :vendor
    has_many :category_products do
           def with_categories
             includes(:category)
           end
    end

    has_many :categories, :through => :category_products

Это мой category_product.rb

  attr_accessible :product_id, :category_id, :purchases_count

    belongs_to :product
  belongs_to :category

  validates_uniqueness_of :product_id, :scope => :category_id

Это мой routes.rb

  mount RailsAdmin::Engine => '/admin', :as => 'rails_admin'
  resources :categories
  resources :vendors do
      resources :products
  end

  authenticated :user do
    root :to => 'home#index'
  end

  root :to => "home#index"
  devise_for :users
  resources :users

Когда я нажимаю Categories при просмотре RailsAdmin, я получаю эту ошибку:

ActionController::RoutingError at /admin/category

Message No route matches {:action=>"show", :model_name=>"category_product", :id=>nil, :controller=>"rails_admin/main"}

Я также получаю эту ошибку, когда нажимаю Category Products

ActiveRecord::StatementInvalid at /admin/category_product

Message SQLite3::SQLException: no such column: category_products.desc: SELECT "category_products".* FROM "category_products" ORDER BY category_products. desc LIMIT 20 OFFSET 0

Все остальные ссылки в RailsAdmin для моих других «обычных» (т.е. не HMT) моделей работают.

Что может быть причиной этого?

Спасибо.

Изменить 1

Для чего это стоит, вот журналы, когда я нажимаю «Категории» внутри Rails Admin:

CodeRay::Scanners could not load plugin nil; falling back to :text
CodeRay::Scanners could not load plugin nil; falling back to :text


Started GET "/admin/category?_pjax=%5Bdata-pjax-container%5D" for 127.0.0.1 at 2012-12-20 22:23:38 -0500
Processing by RailsAdmin::MainController#index as HTML
  Parameters: {"_pjax"=>"[data-pjax-container]", "model_name"=>"category"}
  Category Load (0.3ms)  SELECT "categories".* FROM "categories" LIMIT 6
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Category Load (0.2ms)  SELECT "categories".* FROM "categories" ORDER BY categories.id desc LIMIT 20 OFFSET 0
  CategoryProduct Load (0.2ms)  SELECT "category_products".* FROM "category_products" WHERE "category_products"."category_id" = 2
  Rendered /.rvm/gems/ruby-1.9.3-p194@apt-605/gems/rails_admin-0.3.0/app/views/rails_admin/main/index.html.haml within layouts/rails_admin/pjax (29.4ms)
Completed 500 Internal Server Error in 43ms
CodeRay::Scanners could not load plugin nil; falling back to :text
CodeRay::Scanners could not load plugin nil; falling back to :text


Started GET "/admin/category" for 127.0.0.1 at 2012-12-20 22:23:40 -0500
Processing by RailsAdmin::MainController#index as HTML
  Parameters: {"model_name"=>"category"}
  Category Load (0.3ms)  SELECT "categories".* FROM "categories" LIMIT 6
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Category Load (0.2ms)  SELECT "categories".* FROM "categories" ORDER BY categories.id desc LIMIT 20 OFFSET 0
  CategoryProduct Load (0.2ms)  SELECT "category_products".* FROM "category_products" WHERE "category_products"."category_id" = 2
  Rendered /.rvm/gems/ruby-1.9.3-p194@apt-605/gems/rails_admin-0.3.0/app/views/rails_admin/main/index.html.haml within layouts/rails_admin/application (30.5ms)
Completed 500 Internal Server Error in 251ms

Изменить 2

Вот суть полной трассировки ошибки. Я использую gem better_errors, поэтому трассировка не выглядит как стандартная ошибка трассировки Rails. Но данные те же.

Изменить 3

Это схема для моих 3 моделей:

CategoryProducts

# == Schema Information
#
# Table name: category_products
#
#  product_id      :integer
#  category_id     :integer
#  purchases_count :integer          default(0)
#  created_at      :datetime         not null
#  updated_at      :datetime         not null

Category

# == Schema Information
#
# Table name: categories
#
#  id         :integer          not null, primary key
#  name       :string(255)
#  created_at :datetime         not null
#  updated_at :datetime         not null

Product

# == Schema Information
#
# Table name: products
#
#  id          :integer          not null, primary key
#  name        :string(255)
#  description :string(255)
#  price       :float
#  vendor_id   :integer
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#  image       :string(255)

Обратите внимание, что CategoryProduct не имеет поля первичного ключа. Это проблема?


person marcamillion    schedule 20.12.2012    source источник
comment
не имеет ничего общего с перемещением ваших ресурсов, поэтому ресурсы :категории делают ресурсы :поставщики ресурсы :продукты ?   -  person Richlewis    schedule 20.12.2012
comment
Хм... не уверен, что понимаю, что вы имеете в виду. Вы имеете в виду вложение products внутри vendors внутри categories?   -  person marcamillion    schedule 20.12.2012
comment
да, это то, что я делал в прошлом без проблем, не говорю, что это исправление, но стоит попробовать, чтобы двигаться дальше :)   -  person Richlewis    schedule 20.12.2012
comment
Я не думаю, что это проблема здесь. Это также изменило бы структуру маршрутов моего приложения, чего я не хочу делать. Зачем мне перемещать do?   -  person marcamillion    schedule 20.12.2012
comment
ты хоть пробовал?   -  person Richlewis    schedule 20.12.2012
comment
Да... и это не исправило эту ошибку... к сожалению :(   -  person marcamillion    schedule 20.12.2012


Ответы (1)


Убедитесь, что все объекты CategoryProduct имеют внешние ключи: category_id и product_id.

CategoryProduct.all.each {|c| raise("Repair #{c.id}") unless c.category && c.product}

Обновление от 21 декабря:

Как я установил новый Rails 3.2.9 с категорией, продуктом и категорией продукта. Код отношения модели идентичен, RailsAdmin с настройками по умолчанию.

И работает без проблем!

Я решил проверить свою гипотезу. Я думаю, возможно, когда вы перешли от HABTM к HM2HM, вы пропустили (забыли) восстановить идентификатор ключевого столбца для CategoryProduct, который теперь является не просто моделью соединения, а независимым объектом.

Итак, ошибка маршрутизации, например:

No route matches {:action=>"show", :model_name=>"category_product", :id=>nil, :controller=>"rails_admin/main"}

может быть результатом отсутствия идентификатора.

Ну, я отключил поле идентификатора CategoryProduct вручную (def id; nil; end).

и да это:

No route matches {:action=>"show", :model_name=>"category_product", :id=>nil, :controller=>"rails_admin/main"}
person Valery Kvon    schedule 21.12.2012
comment
Контроллер для category_products? - person marcamillion; 21.12.2012
comment
К сожалению, это не сработало :( Я также создал контроллер category_products с действием show, и он все еще выдает эту ошибку. - person marcamillion; 21.12.2012
comment
Я добавил вывод журнала, который происходит всякий раз, когда возникает эта ошибка (по крайней мере, первая ошибка в моем вопросе). - person marcamillion; 21.12.2012
comment
Хорошо, посмотрите на таблицу БД 'category_products' (непосредственно через любой клиент БД): все элементы должны иметь product_id и category_id. Во время активной разработки мы можем позволить этому происходить очень часто. нет такого столбца: category_products.desc: - забавные вещи. )) - person Valery Kvon; 21.12.2012
comment
я ищу источники rails_admin. Ничего общего с маршрутами. проблема в чем-то другом - person Valery Kvon; 21.12.2012
comment
Делать это на моей консоли? Или в действии контроллера? - person marcamillion; 21.12.2012
comment
Кстати... разве это не временное решение? Я хочу предотвратить эту ошибку, когда я отправляю ее в Heroku. - person marcamillion; 21.12.2012
comment
Кроме того, я только что попробовал это в своей консоли, и это не помогло :( Все еще получаю эту ошибку. К вашему сведению: я вернул routes.rb в исходное состояние. - person marcamillion; 21.12.2012
comment
Я проверил таблицу БД category_products в браузере SQLite. Все предметы имеют как product_id, так и category_id. - person marcamillion; 21.12.2012
comment
Я обновил вопрос со ссылкой на суть с трассировкой. - person marcamillion; 21.12.2012
comment
что происходит, когда вы переопределяете свой CategoryProduct с помощью: def id; 4; конец ? похоже, что у вашей модели нет идентификатора или что-то в этом роде. - person Valery Kvon; 21.12.2012
comment
Я повторил ваше приложение: Rails 3.2.9, Category/Product/CategoryProduct + RailsAdmin. Посмотрите результаты :) - person Valery Kvon; 21.12.2012
comment
Я обновил вопрос со схемами для моих 3 моделей. Можете ли вы сказать мне, если там чего-то не хватает? - person marcamillion; 22.12.2012
comment
да это так. удалите :id =› false из переноса category_products, удалите таблицу и создайте ее снова - person Valery Kvon; 22.12.2012
comment
Учитывая, что вы были моей феей-крестной в этих вопросах, взгляните на это: stackoverflow.com/questions/13899686/? :D - person marcamillion; 22.12.2012
comment
Argh... теперь получаю column doesn't exist error от Heroku - stackoverflow.com/questions/13998507/ - person marcamillion; 22.12.2012
comment
Полностью прибил @ValeryKvon. У меня была модель с _id: nil, и это мешало загрузке страницы. Спасибо! - person colllin; 26.06.2014