Rails 3.2:has_and_belongs_to_many - 在两个现有记录之间建立关联时的Na​​meError

时间:2013-12-30 19:37:16

标签: ruby-on-rails-3 activerecord

我有这三种模式:

class Cve < ActiveRecord::Base
  has_and_belongs_to_many :son_vulns
end

class Cpe < ActiveRecord::Base
  has_and_belongs_to_many :son_vulns
end

class SonVuln < ActiveRecord::Base
  has_and_belongs_to_many :cves
  has_and_belongs_to_many :cpes
end

我为每个HABTM关系设置了连接表,分别命名为:cpe_son_vulnscve_son_vulns。这两个连接表的结构相同。

在IRB中这很好用:

> the-cpe = Cpe.first
> the-son-vuln.cpes << the-cpe

然而,当我为Cve模型运行相同的序列时:

> the-cve = Cve.first
> the-son-vuln.cves << the-cve

我收到此错误:

NameError: uninitialized constant SonVuln::Cfe
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/activerecord-3.2.16/lib/active_record/inheritance.rb:111:in `compute_type'
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/activerecord-3.2.16/lib/active_record/reflection.rb:172:in `klass'
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/activerecord-3.2.16/lib/active_record/associations/collection_association.rb:148:in `transaction'
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/activerecord-3.2.16/lib/active_record/associations/collection_association.rb:134:in `concat'
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/activerecord-3.2.16/lib/active_record/associations/collection_proxy.rb:118:in `<<'
    from (irb):34
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/railties-3.2.16/lib/rails/commands/console.rb:47:in `start'
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/railties-3.2.16/lib/rails/commands/console.rb:8:in `start'
    from /Users/don/.rvm/gems/ruby-1.9.3-p484@sonsafe/gems/railties-3.2.16/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

我无法理解为什么Rails会尝试生成一个常量:SonVuln::Cfe。我已经在我的所有代码中进行了搜索,序列“cfe”似乎没有出现在哪里。为什么Rails喜欢Cpe但没有Cve?关于Rails试图在这里做什么的任何想法?

2 个答案:

答案 0 :(得分:0)

它找不到Cfe,因为你的模型被称为Cpe和Cve。不是Cfe。我在这里错过了什么吗?

你应该更好地命名你的模型。

你是否在意外的任何地方使用'Cfe'?做一个项目广泛的grep。

答案 1 :(得分:0)

我发现这是Rails变形规则的问题。似乎Rails会将以“________ves”结尾的任何复数单词单词化为以“________fe”结尾的非复数单词。这个问题很难找到,因为Rails的变形使一个单词以“_________ve”结尾为“________ ves”。

所以在我的情况下,Rails将我的“Cve”课程带到复数状态:“Cves”,然后将其重新归结为“Cfe”。绝对不是对称的转型!通过使用控制台可以看到这一点:

1.9.3p484 :001 > "cves".singularize
 => "cfe" 
1.9.3p484 :002 > "cve".pluralize
 => "cves" 

这是修复。在config/initializers/inflections.rb我插入了此代码:

ActiveSupport::Inflector.inflections do |inflect|
  inflect.clear :inflection_cfe
  inflect.irregular 'cve', 'cves'
end

我在这个answer

的帮助下想出来了