私はレールに慣れていないので、データベースでいくつかのエンティティと関係を指定するのに問題があります。
次のエンティティを想定しましょう。
レーサーエンティティ
移行ファイルは次のようになります。
class CreateRacers < ActiveRecord::Migration
def self.up
create_table :racers, options: "ENGINE=InnoDB" do |t|
t.string :email, limit: 60, null: false
end
add_index :racers, :email, unique: true
execute "ALTER TABLE racers MODIFY id INT UNSIGNED AUTO_INCREMENT;"
end
def self.down
drop_table :racers
end
end
モデル ファイルは次のようになります。
class Racer < ActiveRecord::Base
attr_accessible :email
validates_uniqueness_of :email
before_save { |racer| racer.email = email.downcase }
# Email validation
VALID_EMAIL_REGEX = /([\w+.]+)@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: {maximum: 60}, format: { with: VALID_EMAIL_REGEX }
has_many :tracks, dependent: :delete_all
end
追跡エンティティ
移行ファイルは次のようになります。
class CreateTracks < ActiveRecord::Migration
def self.up
create_table :tracks, options: "ENGINE=InnoDB" do |t|
t.column :user_id, 'integer unsigned', null: false
t.string :description, limit: 250, null: false
t.string :image, null: true
end
execute "ALTER TABLE tracks MODIFY id INT UNSIGNED AUTO_INCREMENT;"
add_foreign_key :tracks, :racers
end
def self.down
remove_foreign_key :tracks, :racers
drop_table :tracks
end
end
モデルファイルは次のようになります。
class Track < ActiveRecord::Base
attr_accessible :description, :image
validates :description, presence: true, length: {maximum: 250}
belongs_to :racer
validates_presence_of :racer_id
has_many :stops, dependent: :delete_all
end
エンティティを停止
移行ファイルは次のようになります。
class CreateStops < ActiveRecord::Migration
def self.up
create_table :stops, options: "ENGINE=InnoDB" do |t|
t.column :track_id, 'integer unsigned', null: false
t.column :coordinates, :point, null: false
t.string :name, limit: 30, null: true
t.column :sequence_order, 'integer unsigned', null: false
end
execute "ALTER TABLE stops MODIFY id INT UNSIGNED AUTO_INCREMENT;"
add_foreign_key :stops, :tracks
end
def self.down
remove_foreign_key :stops, :tracks
drop_table :stops
end
end
モデルファイルは次のようになります。
class Stop < ActiveRecord::Base
attr_accessible :coordinates, :name, :sequence_order
validates :name, presence: true, length: {maximum: 30}
validates :coordinates, presence: true
validates :spot_sequence_order, presence: true
belongs_to :track
validates_presence_of :track_id
has_one :challenge, dependent: :delete_all
end
Challenge、Puzzle、Quiz、QuizOption エンティティ (問題がある場所)
上記のStopエンティティhas_one challenge を見てきましたが、そのChallengeをQuizまたはPuzzleにしたいと考えています。Challenge はStopに属します。これまでのところ、次の移行があります。
class CreatePuzzles < ActiveRecord::Migration
def self.up
create_table :puzzles, options: "ENGINE=InnoDB" do |t|
t.string :image_path, null: false
t.int :ver_split, null: false, default: 4
t.int :hor_split, null: false, default: 4
end
execute "ALTER TABLE puzzlies MODIFY id INT UNSIGNED AUTO_INCREMENT;"
end
def self.down
drop_table :quizzes
end
end
class CreateQuizzes < ActiveRecord::Migration
def self.up
create_table :quizzes, options: "ENGINE=InnoDB" do |t|
t.string :question, null: false
end
execute "ALTER TABLE quizzes MODIFY id INT UNSIGNED AUTO_INCREMENT;"
end
def self.down
drop_table :quizzes
end
end
そして、以下のモデル
class Puzzle < ActiveRecord::Base
attr_accessor :image_path, :ver_split, hor_split
validates :image_path, presence: true, allow_blank: false
validates :ver_split, allow_blank: false
validates :hor_split, allow_blank: false
belongs_to :stop
end
class Quiz < ActiveRecord::Base
attr_accessor :question
validates :question, presence: true, length: { maximum: 255 }, allow_blank: false
belongs_to :spot
has_many :quiz_options
end
クイズにはいくつかの答えがあり、1 つ以上が正解です。
class CreateQuizOptions < ActiveRecord::Migration
def self.up
create_table :quiz_options do |t|
t.column :quiz_id, 'integer unsigned', null: false
t.string :option, null: false
t.boolean :is_correct, null: false, default: false
end
add_foreign_key :quiz_options, :quizzes
execute "ALTER TABLE quiz_options MODIFY id INT UNSIGNED AUTO_INCREMENT;"
end
def self.down
remove_foreign_key :quiz_options, :quizzes
drop_table :quiz_options
end
end
class QuizOption < ActiveRecord::Base
attr_accessor :option, :is_correct
validates :option, presence: true, length: { maximum: 255 }
validates_inclusion_of :is_correct, in: [true,false]
belongs_to :quiz
validates_presence_of :quiz_id
end
質問
この目標を達成するには、移行、モデル、およびコントローラーをどのように指定すればよいですか?
STI と Polymorphic-Associations の例をいくつか見つけましたが、どれを適用すればよいのか、このケースにどのように適用するのかわかりません。
最初に、STI を使用してChallengeテーブルで必要なすべてのフィールドを宣言しようとしました。次に、 QuizおよびPuzzleモデルがChallengeモデルから継承されます。問題は、 has_many :quiz_optionsをどこに置くべきかわからないことです。
次に、こことここで説明されているポリモーフィック アソシエーションを使用しようとしましたが、この特定のケースにそれを適応させる方法を正直に理解できません。
前もって感謝します。
編集:MySQLを使用していることを忘れていました。また、空間データ型 (rgeo、activerecord-mysql2spatial-adapter) およびforeign_keys (foreigner) を管理するための gem もいくつかあります。