5

ユーザーに「ランダム」オプションを提供して、データベース (letsgos テーブル内) から使用する以前に作成された日付のアイデアを選択できるようにしたいと考えています。ユーザーがフォームに記入して、行きたい日付を提案できる「Let's Go...」セクションがあります。自分でデートのアイデアを思いつくことができないユーザーがいるでしょう. したがって、独自の日付を作成できないユーザーのために、クリックするたびに (データベースからの) 日付をフォームに挿入する「ランダム」ボタンを提供したいと考えています。letsgos テーブルからのデータベース内の日付がcontentありtag、それらに割り当てられます。ユーザーがランダムにクリックすると、フォームにコンテンツとタグが入力されます (ランダムにクリックするたびに、データベースからの新しいデータが表示されます)。JavaScript の経験がないので、正しい方法で行っているかどうかわかりません。

/views/letsgos/_form.html.erb:

   <%= form_for(@letsgo) do |f| %>
    <div class="field">
        <%= f.text_area :content, placeholder: "Propose new date..." %>
        </div>
        <%= f.select :tag, options_for_select( [["Select One", ""], "Eat/Drink", "Listen/Watch", "Play", "Explore", "Other"]) %>
        <a href="/letsgos/random" class="ajax">Click here for a Random letsgo</a>
        <%= f.submit "Post" %>

        <% end %>

/views/layouts/application.html.erb

<head>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>

<script>
  $(document).ready(function() {
    $('.ajax').click(function() {
      $.get(this.href, function(response) {
        console.log(response);
        $('body').html(response); 
      });
    });
  });
<script>
</head>

レッツゴーコントローラー:

  def create
    @letsgo = current_user.letsgos.build(letsgo_params)
    if @letsgo.save
      flash[:success] = "Date posted!"
      redirect_to root_url
else
      flash[:error] = "Date was not posted!"
      redirect_to root_url
end
end
  def destroy
    @letsgo.destroy
    redirect_to root_url
  end

def random
  @letsgo = Letsgo.random.first
  if request.xhr?
  end
end

private

def letsgo_params
  params.require(:letsgo).permit(:content, :tag)
end

def correct_user
  @letsgo = current_user.letsgos.find_by(id: params[:id])
  redirect_to root_url if @letsgo.nil?
end

キャッシュ列の移行:

rails g migration add_ids_count

def self.up
add_column :letsgos, :ids_count, :integer, :default => 0

 Letsgo.reset_column_information
    Letsgo.all.each do |l|
      l.update_attribute :id_count, l.id.length
    end
  end

 def self.down
    remove_column :letsgos, :id_count
  end
end
4

3 に答える 3

3

Letsgoこれに対する創造的な解決策は、Antarr Byrd の提案でパフォーマンスが心配な場合は、の ID の配列を格納するキャッシュ列を設定することです。Letsgo.pluck(:id)基本的に、これはDBの単一の列にキャッシュします。(これは、Letsgos の保存後および/または削除後のフックのワーカーで行うこともできます。) これは、何らかのバッファーで行うか、1 時間ごとのタスクとして行うことをお勧めします。

次に、これを JavaScript 配列 (letsgos_ids_array例) として取り込み、その配列の長さに基づいて Math.random() 値を作成し、それを .find() に送信することができます。もちろん、配列の長さを直接出力することもできます。

var item_index = Math.floor(Math.random() * letsgos_ids_array_length);
$.get("/letsgos/random", {
    "ind" : item_index
}, function(data){
    /* do something with the data */
});

次に、このインデックスを使用して、データベースの配列から実際の ID 値を引き出すことができます。

letsgoarray = Letsgosarray.first # this is the single-column "cached" array of IDs
item_id = letsgosarray[params[:id_index]]
@random_letsgo = Letsgos.find(item_id)
format.json do {
    render json: @random_letsgo
}

配列へのアクセスは高速で、単一の db 列のクエリも高速です。

于 2013-11-11T15:04:28.863 に答える
1

ここでは、ランダム行についてよく読んでいます。

http://jan.kneschke.de/projects/mysql/order-by-rand/

于 2013-10-22T13:49:20.133 に答える
0

私はこれをやったことがありませんが、おそらくできるでしょう

def random
  Letsgos.find(Letsgo.pluck(:id).sample)
end
于 2013-10-21T21:00:39.430 に答える