如何创建一个删除/销毁而没有错误的rails habtm?

时间:2010-01-18 05:00:25

标签: ruby-on-rails has-and-belongs-to-many nameerror

我创建了一个简单的示例作为完整性检查,但仍然无法破坏rails中has_and_belongs_to_many关系两侧的项目。

每当我尝试从任一表中删除对象时,我都会收到可怕的NameError /“uninitialized constant”错误消息。

为了演示,我创建了一个带有Boy类和Dog类的示例rails应用程序。我为每个人使用了基本的脚手架,并创建了一个名为boys_dogs的链接表。然后我添加了一个简单的before_save例程,在创建一个男孩的任何时候创建一个新的“狗”并建立一种关系,只是为了轻松设置。

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  

schema.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中的NameError#destroy
  未初始化的常数男孩::狗

跟踪看起来像:

  

/Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:105:in const_missing'
(eval):3:in
destroy_without_callbacks'
  /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/callbacks.rb:337:in destroy_without_transactions'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:229:in
发送'
  ...

感谢。

2 个答案:

答案 0 :(得分:3)

我没有看到你的破坏回调,但我确实看到了一些问题。首先,您的关联需要小写。所以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,因为构建实际上不会保存新的狗对象。

答案 1 :(得分:0)

这里接受的答案解决了我的问题,只是为了创造另一个问题。

以下是我的模型对象:

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使用关联的名称作为表名。我的应用程序在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文档中未提及