1

私は3つのモデルを持っています:質問、オプション、ルール

質問has_manyオプション; オプションにはquestion_idの外部キーが必要です

ルールテーブルは3つのforeign_keysで構成されています。

  • 2列/question_idsへの参照->「assumption_question_id」および「consequent_question_id」という名前の外部キー
  • 1列/option_idへの参照->option_idまたはcondition_idという名前の外部キー

ルールの関連付け:質問has_manyルール; およびオプションhas_oneルール

このための移行を作成する方法と、モデルに作成する「has_many」/「belongs_to」ステートメント、およびモデルに含めることができる「:foreign_key」オプションにどのように関連付けられるかを理解したいと思います。

オプションの移行でこれを使用しましたが、外部キーに関して「add_index」ステートメントがどのように機能し、ルールの移行でどのように使用できるかわかりません:(質問モデルとオプションモデルには適切なhas_manyステートメントとbelongs_toステートメントがあります-そして正常に動作します)

class CreateOptions < ActiveRecord::Migration
  def change
    create_table :options do |t|
      t.integer :question_id
      t.string :name
      t.integer :order

      t.timestamps
    end
    add_index :options, :question_id
  end
end

お手伝いありがとう!

4

3 に答える 3

2

add_index指定された列にインデックスを追加します。それ以上は追加しません。

Railsは、外部キーを管理するための移行でネイティブサポートを提供しません。そのような機能は外国人のような宝石に含まれています。そのgemのドキュメントを読んで、その使用方法を確認してください。

関連付けについては、質問で言及した列を各テーブルに追加するだけです(提供した移行は問題ないようですが、欠落している可能性があり:rule_idますか?)

次に、モデルの関連付けを指定します。はじめに

class Question < ActiveRecord::Base
  has_many :options
  has_many :assumption_rules, class_name: "Rule"
  has_many :consequent_rules, class_name: "Rule"
end

class Rule < ActiveRecord::Base
  belongs_to :option
  belongs_to :assumption_question, class_name: "Question", foreign_key: :assumption_question_id, inverse_of: :assumption_rules
  belongs_to :consequent_question, class_name: "Question", foreign_key: :consequent_question_id, inverse_of: :consequent_rules
end

class Option < ActiveRecord::Base
  belongs_to :question
  has_one    :rule
end

これは単なる(テストされていない)開始です。オプションが欠落している可能性があります。

読むことを強くお勧めします

編集:コメントの質問に答える

class Option < ActiveRecord::Base
  belongs_to :question
  # ...

は、テーブルの列にテーブルのレコードの値が格納されてbelongs_toいることをレールに通知します。Railsは、列の名前がシンボルに基づいていると推測します。それが列の名前であるかのようにオプションを指定することにより、テーブル内の別の列を参照するようにrailsに指示できます。上記の私のコードのクラスはこのようにオプションを使用していることに注意してください)question_idoptionsidquestionsquestion_id:questionoptionsforeign_key: :question_reference_identifierRuleforeign_key

移行は、Railsがデータベースでコマンドを読み取って実行するための指示にすぎません。モデルの関連付けhas_many、、belongs_toなど)は、Active Recordでデータをどのように処理するかをRailsに通知し、データを操作するための明確で簡単な方法を提供します。モデルと移行が相互に作用することはありません。どちらも独立してデータベースと対話します。

于 2012-07-12T18:55:04.427 に答える
2

注:私は問題を解決するためにこの方法を見つけました。中国からの優しさ。

RailsAdminを持っている場合、両方の質問フィールド(assumption_question_id、consequent_question_id)の1つのフィールドが質問のidと等しい限り、1つの質問のすべてのルールを表示できることに気付くかもしれません。

これについて詳細なテストを行ったところ、Railsは常にto_sql出力を行う条件「question_id=[current_id]」を生成することがわかりました。

SELECT `rules`.* FROM `rules` WHERE `rules`.`question_id` = 170

そして、次のモデルが

class Question < ActiveRecord::Base
  has_many :options
  # Notice ↓
  has_many :rules, ->(question) { where("assumption_question_id = ? OR consequent_question_id = ?", question.id, question.id) }, class_name: 'Rule'
  # Notice ↑
end

Question.take.rules.to_sqlを次のようにします

SELECT `rules`.* FROM `rules` WHERE `rules`.`question_id` = 170 AND (assumption_question_id = 170 OR consequent_question_id = 170)

私たちはまだ煩わしさを乗り越えていないquestion_idので、どのように適切に説明または調整しても、私たちの条件はその「AND」に従います。

次に、それに乗る必要があります。どうやって?

ここをクリックすると、その方法がわかります。セクター8.1を検索すると、次のように表示されます。

Article.where(id: 10, trashed: false).unscope(where: :id)
# SELECT "articles".* FROM "articles" WHERE trashed = 0

それからそれをしましょう:

class Question < ActiveRecord::Base
  has_many :options
  # Notice ↓
  has_many :rules, ->(question) { unscope(where: :question_id).where("assumption_question_id = ? OR consequent_question_id = ?", question.id, question.id) }, class_name: 'Rule'
  # Notice ↑
end

class Rule < ActiveRecord::Base
  belongs_to :option
  belongs_to :assumption_question, class_name: "Question", foreign_key: :assumption_question_id, inverse_of: :assumption_rules
  belongs_to :consequent_question, class_name: "Question", foreign_key: :consequent_question_id, inverse_of: :consequent_rules
end

class Option < ActiveRecord::Base
  belongs_to :question
  has_one    :rule
end

全部終わった。

ついに

これはstackoverflowでの私の最初の答えであり、このメソッドは他のどこにも見つかりません。

読んでくれてありがとう。

于 2016-11-04T15:58:27.633 に答える
0

次のように、モデルに外部キーを設定できます。

class Leaf < ActiveRecord::Base
belongs_to :tree, :foreign_key => "leaf_code"
end

移行時にこれを指定する必要はありません。railsはモデルクラス定義から外部キーをプルします。

于 2013-01-10T21:32:27.960 に答える