sql >> データベース >  >> RDS >> Mysql

Railsサーベイスタイルアプリケーション-オプションですべての回答を表示

    関係を少し修正することから始めましょう:

    class Question < ActiveRecord::Base
      has_many :options
      has_many :answers
      has_many :users, through: :answers
    end
    

    has_many :answers, :through => :optionsには技術的に問題はありません。 ただし、answers.question_idには直接的な関係があるためです。 optionsを実行する必要はありません 関係の表。

    カウントの表示

    単純に行った場合:

    <td class="optionCell"><%= option.answers.count %></td>
    

    これにより、厄介なn+1が作成されます 各オプションの回答の数を取得するためのクエリ。したがって、私たちがやりたいのは、カウンターキャッシュを作成する ことです。 オプションテーブルに集計を保存します。

    列を追加するための移行を作成することから始めましょう:

    rails g migration AddAnswerCounterCacheToOptions answers_count:integer
    rake db:migrate
    

    次に、関連付けられたレコードを作成するときに集計を更新するようにActiveRecordに指示します。これは、counter_cache: trueであるため、少し奇妙に見えます。 宣言はbelongs_toにあります コラムが反対側にある間、それはARがどのように機能するかです。

    class Option < ActiveRecord::Base
      belongs_to :question
      has_many :answers
    end
    
    class Answer < ActiveRecord::Base
      belongs_to :user
      belongs_to :question
      belongs_to :option, counter_cache: true
    end
    

    ここに小さな障害があります。すでにレコードがある可能性があるため、正しいカウンターがあることを確認する必要があります。これはコンソールから実行できますが、長期的にはを実行することをお勧めします。レーキタスクを作成する

    Option.find_each { |option| Option.reset_counters(option.id, :answers) }
    

    各オプションを取得してカウントを更新する必要があるため、これには少し時間がかかる場合があります。

    これで、次のように集計を表示できます:

    <% question.options.each do |option| %>
      <tr class="backgroundColor1">
        <td class="optionCell"><%= option.option_text %></td>
        <td class="optionCell"><%= option.answers.size %></td>
      </tr>
    <% end %>
    

    .size カウンターキャッシュ列を使用するのに十分賢いですが、カウントのクエリにフォールバックします。これはテストに適しています。




    1. 重複する行を削除して、最も古い行のみを残しますか?

    2. onClickjavascript関数を介してPHPを使用してMySqlデータベースを更新する

    3. PostgreSQL-列の値が変更されました-クエリ最適化を選択します

    4. cronとパスワードのセキュリティによって起動されたMysqldump