##問題の概要
railsで求人情報サイトの設計を行っており、表題にあるような、
相互にポリモーフィック(?)な中間テーブルを使った設計が理想かと考えているのですが、
・パフォーマンスやスケールの観点で問題がないか(特にここの知識が皆無です)
・DRY、かつ、リーダブルなコードがかけるか(現状、ここはクリアできているのではないかと考えていますが、まだまだ初心者なので不安です)
などなど、設計に問題がないかをアドバイス頂きたいです。
以下にサービスの仕様やモデルのリレーションを実際どのように書いているかを説明致しますので、ご教授頂ければ嬉しいです。。!
##サービスの仕様
- 求人の検索、企業の検索、企業経営者の検索を、それぞれ独立して行える(求人データベース、企業データベース、経営者データベースが独立して存在するということです。)
- それぞれの検索軸には、業種や都道府県など、共通しているものが多い
##モデルの設計をどのようにしているか
・Jobモデル(求人情報)
・Companyモデル(求人をする企業情報)
・Presidentモデル(企業の経営者情報)
上記、「検索の対象」となる3つのモデルと、
・Genreモデル(業界。IT、コンサル、飲食、のような項目。)
・Areaモデル(都道府県)
上記2つの検索項目となる2つのモデルがあり、
・ContentsTaxonomy
「検索の対象」と「検索項目」を繋ぐモデルを用意しました。
それぞれ、
「検索の対象」のモデルは、
job.rb
ruby
1class Job < ActiveRecord::Base 2 has_many :contents_taxonomies, :as => :contentable 3 has_many :genres, through: :contents_taxonomies, source: :taxonomisable, source_type: 'Genre' 4 has_many :areas, through: :contents_taxonomies, source: :taxonomisable, source_type: 'Area' 5end
company.rb
ruby
1class company < ActiveRecord::Base 2 has_many :contents_taxonomies, :as => :contentable 3 has_many :genres, through: :contents_taxonomies, source: :taxonomisable, source_type: 'Genre' 4 has_many :areas, through: :contents_taxonomies, source: :taxonomisable, source_type: 'Area' 5end
Presidentも同様、、
「検索項目」は、
genre.rb
ruby
1class Genre < ActiveRecord::Base 2 has_many :contents_taxonomies, :as => :taxonomisable 3 has_many :jobs, through: :contents_taxonomies, source: :contentable, source_type: 'Job' 4 has_many :company, through: :contents_taxonomies, source: :contentable, source_type: 'Company' 5 has_many :president, through: :contents_taxonomies, source: :contentable, source_type: 'President' 6end
Areaも同様、
最後に、contents_yaxonomy.rbは、
ruby
1class ContentsTaxonomy < ActiveRecord::Base 2 belongs_to :taxonomisable, polymorphic: true 3 belongs_to :contentable, polymorphic: true 4end
としています。
また、中間テーブルのmigrateは、
ruby
1class CreateContentsTaxonomies < ActiveRecord::Migration 2 def change 3 create_table :contents_taxonomies do |t| 4 t.references :taxonomisable, polymorphic: true, index: true 5 t.integer :taxonomisable_id 6 t.string :taxonomisable_type 7 8 t.references :contentable, polymorphic: true, index: true 9 t.integer :contentable_id 10 t.string :contentable_type 11 12 t.timestamps null: false 13 end 14 end 15end
となっております。
これで以下のようなリーダブルなコードは実現できています。
ruby
1job = Job.new 2job.genres << Genre.find(1) #あらかじめGenreにname: 'IT業界'をいれてある。 3job.genres 4=> [#<Genre:0x007f04e2a3e330 5 id: 1, 6 name: "IT業界", 7 created_at: Sat, 31 Oct 2015 12:56:32 UTC +00:00, 8 updated_at: Sat, 31 Oct 2015 12:56:32 UTC +00:00>]
検索なども、求人、企業、企業経営者のどの検索も同じようなコード使いまわせるかと思ってます。
##パフォーマンスなど設計に問題ないか。。?
以上が設計(実際よりも簡略化はされてますが)の概要です。
ポリモーフィックを使わずに、JobとGenreの中間テーブル、JobとAreaの中間テーブル、、、と大量に中間テーブルを作る方法もあると思うのですが、煩雑な気がしてこの設計に至りました。
このような設計例を見たことがなく、ポリモーフィックは気をつけて使えという記事も多数あったのでアドバイス頂きたいです。
宜しくお願いします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。