2016-05-11 20 views
2

レールの複数形に問題があります。モデル作成時に複数のレールが複数ある場合

私はCompanySkillという名前のモデルを持っています(これは、企業が所有するスキルを表しています)。モデルレールを作成するときcompany_skillsの代わりにcompanies_skillで複数化するので、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 
+0

なぜhas_many:companies_skill を使用しませんか? – Boltz0r

+2

私はできるが、言語学的には会社has_many:company_skillsはスキル** S ** **を表しているので、それはより良いです** **会社は –

+0

を持っています。 CompanySkillのほかに、あなたのアプリに他の "スキル"モデルがありますか? EmployeeSkillのように、多分? –

答えて

5

あなたは2つのオプションがあります。

まず、この名前のインフレクターを無効にすることができます。 config/initializers/inflections.rbに以下を追加します。また

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

、おそらく最良の解決策を、あなたは関連のクラス名を指定することができます。他の人が言っているようcompany_skillはデフォルトでcompany_skillsへのレールによってpluralisedしなければならないため、これらのソリューションのどちらも、要求されるべき、けれども

has_many :company_skills, class_name: 'CompanySkill' 

:あなたのモデルでは、このようなものを使用します。

+0

これは役に立ちません。なぜなら、Rails *はすでに 'company_skill'を正しく反映しているからです。あなたは、同じ変曲*で変項を上書きしています。 – meagar

+0

クラス名を指定する私の好ましい解決方法 – Jon

+0

Railsが既に正しい複数化を行っている場合、ここには何か他のものがあります。 'class_name:'を指定したり、カスタム変項を追加したりする必要はありません。問題が誤って伝えられているため、問題を解決することはできません。 – meagar

1

私は問題を修正したと思います。誤って複数形モデルを作成し

rails generate model CompanySkill 

は私が最初でモデルを生成しました。

 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 

私は、テーブル名を変更し、移行を編集した:

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 

示唆したようにその後、私は最終的にモデルにself.table_nameを使用:

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 

だから今もしコンソールIからcompany_skillを作成してからCompany.first.skillsを実行します。スキルを取得できます

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">]> 

私はself.table_nameを削除する場合は、しかし、私はエラーを取得するActiveRecord::StatementInvalid: Could not find table 'companies_skill'

私はこの権利をやっていますか?

+1

問題を正しく解決していますが、する必要はありません。 Railsは、あなたが主張しているように動作しません。ここには診断されていない問題がいくつかあります。 Rails 4.2.4をインストールして、 'rails g model Company'、' rails g model Skill '、' rails g model CompanySkill'を実行しても、Rails *は*あなたが経験している動作を生成しません。 – meagar

+1

@meagar ........私は変態 'inflect.plural"会社 "、"企業 "' ..........私は申し訳ありません、なぜ私は知らない。私はその質問を取り除くべきですか? –

+2

@Fabioそれは奇妙な動作を説明します! – Pavan

関連する問題