Как создать rails habtm, который удаляет / уничтожает без ошибок?

StackOverflow https://stackoverflow.com/questions/2083989

Вопрос

Я создал простой пример для проверки работоспособности и, похоже, до сих пор не могу уничтожить элемент по обе стороны отношения has_and_belongs_to_many в rails.

Всякий раз, когда я пытаюсь удалить объект из любой таблицы, я получаю страшное сообщение об ошибке NameError / "неинициализированная константа".

Чтобы продемонстрировать, я создал пример приложения rails с классами Boy и Dog.Я использовал базовый каркас для каждого из них и создал таблицу ссылок под названием boys_dogs .Затем я добавил простую процедуру before_save, позволяющую создавать новую "собаку" каждый раз, когда был создан мальчик, и устанавливать отношения, просто чтобы упростить настройку.

собака.рб

class Dog < ActiveRecord::Base  
  has_and_belongs_to_many :Boys  
end  

мальчик.рб

class Boy < ActiveRecord::Base  
  has_and_belongs_to_many :Dogs  

  def before_save  
    self.Dogs.build( :name => "Rover" )  
  end  

end  

схема.rb

ActiveRecord::Schema.define(:version => 20100118034401) do

  create_table "boys", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "boys_dogs", :id => false, :force => true do |t|
    t.integer  "boy_id"
    t.integer  "dog_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "dogs", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

Я видел много сообщений здесь и в других местах о подобных проблемах, но решения обычно используют belongs_to, а имена классов во множественном числе / единственном числе путаются.Я не думаю, что здесь дело в этом, но я попытался переключить инструкцию habtm на использование имени в единственном числе, просто чтобы посмотреть, помогло ли это (безуспешно).Кажется, я упускаю здесь что-то простое.

Фактическое сообщение об ошибке является:

Ошибка имени в BoysController#уничтожить
неинициализированный постоянный Мальчик::Собаки

След выглядит как:

/Библиотека/Ruby/Gems/1.8/gems/activesupport-2.3.4/Библиотека/active_support/dependencies.rb:105:в const_missing'
(eval):3:in
destroy_without_callbacks'
/Библиотека/Ruby/Gems/1.8/gems/activerecord-2.3.4/Библиотека/active_record/обратные вызовы.rb:337:в destroy_without_transactions'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:229:in
отправить'
...

Спасибо.

Это было полезно?

Решение

Я не вижу вашего обратного вызова destroy, но я вижу пару проблем.Во-первых, ваши ассоциации должны быть в нижнем регистре.Так что dog.rb должен быть:

class Dog < ActiveRecord::Base  
  has_and_belongs_to_many :boys  
end  

и boy.rb должен быть:

class Boy < ActiveRecord::Base  
  has_and_belongs_to_many :dogs  

  def before_save  
    self.dogs.build( :name => "Rover" )  
  end
end

Во-вторых, я полагаю, что вы хотите использовать self.dogs.create вместо того , чтобы self.dogs.build выше, поскольку сборка фактически не сохранит новый объект dog.

Другие советы

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

Вот мои модельные объекты:

class Complex < ActiveRecord::Base
   set_table_name "Complexes"
   set_primary_key "ComplexID"
   has_and_belongs_to_many :amenities
end

class Amenity < ActiveRecord::Base
   set_table_name "Amenities"
   set_primary_key "AmenityID"
end

Rails использует имя ассоциации в качестве имени таблицы при создании запроса select.Мое приложение работает в Unix с устаревшей базой данных MySQL, а имена моих таблиц чувствительны к регистру и не соответствуют соглашениям Rails.Всякий раз, когда мое приложение действительно пыталось загрузить ассоциацию, я получал исключение, что MySQL не смог найти таблицу amenities:

SELECT * FROM `amenities` 
INNER JOIN `ComplexAmenities` ON `amenities`.AmenityID = `ComplexAmenities`.AmenityID  
WHERE (`ComplexAmenities`.ComplexID = 147 )

Я искал и искал и не мог найти способ указать Rails использовать правильный регистр для имени таблицы.В отчаянии я попытался передать :table_name опция для habtm, и это сработало.Моя новая сложная модель выглядит следующим образом:

class Complex < ActiveRecord::Base
   set_table_name "Complexes"
   set_primary_key "ComplexID"
   has_and_belongs_to_many :amenities, :table_name => 'Amenities'
end

Это работает под управлением Rails 2.3.5.

Этот вариант является не упоминается в документах Ruby on Rails.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top