创建模型时错误的轨道复数

时间:2016-05-11 10:59:11

标签: ruby-on-rails ruby ruby-on-rails-4

我遇到有轨道复数的问题。

我有一个名为CompanySkill的模型(代表公司拥有的技能)。在创建模型轨道时,使用companies_skill而不是company_skills对其进行复数化,因此当我需要设置has_many :company_skills关联轨道时,不使用该模型。

这个问题的正确解决方案是什么?我想的是使用变形,但我不知道它是否是正确的解决方案和/或有更好的解决方案。

我正在从控制台生成模型:

rails generate model CompanySkill
  invoke  active_record
  create    db/migrate/20160511111048_create_companies_skill.rb
  create    app/models/company_skill.rb
  invoke    test_unit
  create      test/models/company_skill_test.rb
  create      test/fixtures/companies_skill.yml

2 个答案:

答案 0 :(得分:5)

您有两种选择。

首先,您可以覆盖此名称的变形器。在config/initializers/inflections.rb中添加以下内容:

ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.irregular 'company_skill', 'company_skills'
end

或者,也许是最好的解决方案,您可以在关联上指定类名。在你的模型中使用这样的东西:

has_many :company_skills, class_name: 'CompanySkill'

虽然正如其他人所说,但这些解决方案都不是必需的,因为默认情况下,company_skill应由Rails复数为company_skills

答案 1 :(得分:1)

Ok I think I fixed the problem.

I first generated the model with:

rails generate model CompanySkill 

which created the model wrongly pluralized.

      invoke  active_record
      create    db/migrate/20160511111214_create_companies_skill.rb
      create    app/models/company_skill.rb
      invoke    test_unit
      create      test/models/company_skill_test.rb
      create      test/fixtures/companies_skill.yml

I then edited the migration changing the table name:

class CreateCompaniesSkill < ActiveRecord::Migration
  def change
    create_table :company_skills do |t|  #was :companies_skill
      t.integer :skill_id
      t.integer :company_id
      t.integer :level

      t.timestamps null: false
    end
  end
end

Then I finally used self.table_name in the model as suggested:

class CompanySkill < ActiveRecord::Base
  self.table_name = "company_skills"
  belongs_to :company, inverse_of: :company_skills
  belongs_to :skill
  validates_presence_of :company
  validates_presence_of :skill
end

So now if from console i create a company_skill and then i do Company.first.skills I can get the skill

Company.first.skills
  Company Load (0.1ms)  SELECT  "companies".* FROM "companies"  ORDER BY "companies"."id" ASC LIMIT 1
  Skill Load (0.4ms)  SELECT "skills".* FROM "skills" INNER JOIN "company_skills" ON "skills"."id" = "company_skills"."skill_id" WHERE "company_skills"."company_id" = ?  [["company_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Skill id: 1, name: "Nihil dolorum maiores et ex temporibus est. Volupt...", school_year: 2, created_at: "02/05/2016 20:09:54", updated_at: "02/05/2016 20:09:54">]>

If I remove self.table_name, though, I get the error ActiveRecord::StatementInvalid: Could not find table 'companies_skill'

Am I doing this right?