1

調査を作成し、調査をユーザーに割り当て、それらのユーザーが調査に記入するための比較的単純なモデル設計があります。それはすべて正常に機能しますが、これらの調査からデータを取得することになると、何が正しいアプローチなのか、特にレールの方法がわからない状態にあります。

私のモデル設計は次のとおりです:(明確にするために、関連するコードのみを残しました)

class Survey < ActiveRecord::Base
  has_many :survey_sections, dependent: :destroy

  has_many :survey_assignments
  has_many :participants , :through => :survey_assignments, :source => :user

  has_many :survey_responses
end

class SurveySection < ActiveRecord::Base
  belongs_to :survey
  has_many :survey_questions, dependent: :destroy
  has_many :survey_options, dependent: :destroy
end

したがって、調査は多くのセクションに分割され、各セクションには多くの質問があり、各セクションには多くのオプションがあります。オプションは基本的に、現在のセクションのすべての質問に対する事前定義された回答です。これは設計上の決定であるため、各質問に多くのオプションを含める必要はありません...

class SurveyQuestion < ActiveRecord::Base
  belongs_to :survey_section
  has_many :survey_answers
end

class SurveyAnswer < ActiveRecord::Base
  belongs_to :survey_option
  belongs_to :survey_question
  belongs_to :survey_response
end

class SurveyOption < ActiveRecord::Base
  #it has 2 fields 'weight'(int) and 'text'(string)
  belongs_to :survey_section
end

医師は、患者にアンケートを割り当て、アンケートに回答できるまでの日付を指定できます。

class SurveyAssignment < ActiveRecord::Base
  #has also a field valid_until(date)  
  belongs_to :user
  belongs_to :survey

  has_many :survey_responses
end

アンケートの回答も記録しています。したがって、ユーザーがフォームに入力するたびに、survey_responses テーブルに新しいレコードが作成されます。これは後で必要になります。これは、ユーザーが受けるべきアンケートを割り当てられる可能性があるスケジューリングの実装のためです [ここに数値を入力] X [日|週|月]。

class SurveyResponse < ActiveRecord::Base
  belongs_to :survey_assignment
  belongs_to :survey
  belongs_to :user

  has_many :survey_answers
 end

次に、調査結果のグラフを表示する必要があります。コードに示されているように、結果は整数 (SurveyOption クラスを参照) であり、特定のユーザーが行った特定の調査について合計する必要があります。したがって、user_id と survey_id があるとしましょう。ユーザーのアンケート回答をすべて取得したいのですが、アンケートの回答ごとに、回答の重み (SurveyOption) の合計が必要です。

次のクエリを実行すると、彼のすべての応答に対する彼の回答の合計が返されます。

SurveyResponse.joins(:survey_answers => :survey_option).where(user_id: 96, survey_id:63).select("survey_option.weight").sum("weight")

しかし、その調査に対するそのユーザーのすべての応答について、次のような配列を取得したいと思います

[[survey_response.created_at.to_i, the_sum_of_weights],[...],[...],....]

では、このようなことを行う最善の方法は何ですか? 純粋にSQLステートメントで考えると、単一のクエリで実行できると思います。

誰かが私にさらに詳しく説明する必要がある場合は、コメントで話し合うことができます. 助けてくれてありがとう。

私が作成しようとしているSQLステートメントは次のとおりだと思います:

SELECT survey_responses.id, survey_responses.created_at, SUM (survey_options.weight) FROM "survey_responses" INNER JOIN "survey_answers" ON "survey_answers"."survey_response_id" = "survey_responses"."id" INNER JOIN "survey_options" ON "survey_options"."id" = "survey_answers"."survey_option_id" WHERE "survey_responses"."user_id" = 96 AND "survey_responses"."survey_id" = 64  GROUP BY survey_responses.id, survey_responses.created_at;

私は自分の質問を解決することに近づいていると思います:)))

4

1 に答える 1

1

ということで、いろいろ調べた結果、ひとつの方法を見つけました。

result = SurveyResponse.joins(:survey_answers => :survey_option).where(user_id: 96, survey_id: 64).select("SUM (survey_options.weight) as score, survey_responses.created_at").group("survey_responses.created_at, survey_responses.id")

次に、ActiveRecord::Relation オブジェクトで find_each 関数を使用できます。

result.find_each do |r|
  puts " score: #{r.score} created_at: #{r.created_at}"
end

find_each は、一度に 1000 レコードのバッチをロードするため、each よりも優れているため、メモリを占有しません。何百万ものレコードをロードすることを想像してください。

誰かがクエリのより良い解決策を持っている場合は、共有してください。私はそれを受け入れます。

于 2013-07-14T01:18:16.157 に答える