5

我想为用户提供一个“随机”选项,以便他们可以从数据库(在letsgos表中)选择以前创建的日期想法。有一个“Let's Go...”部分,用户可以填写表格并提出他们想要继续的日期。将会有一些用户无法自己想出约会的想法。因此,对于那些无法创建自己的日期的用户,我想提供一个“随机”按钮,每次点击都会在表单中插入一个日期(来自数据库)。来自letsgos 表的数据库中的日期具有contenttag分配给它们。当用户随机点击时,它应该使用内容和标签填充表单(每次随机点击都应该显示来自数据库的新数据)。我没有任何 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>

Letsgo控制器:

  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 建议的性能,一个创造性的解决方案是设置一个缓存列来存储 's 的 ID 数组。基本上,这会将数据缓存Letsgo.pluck(:id)在数据库的单个列中。(也许在 Letsgos 的保存后和/或删除后挂钩中的工作人员中执行此操作。)我建议在某种缓冲区中执行此操作,或者作为每小时任务执行此操作。

然后,您可以将其作为 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 */
});

然后,该索引可用于从 db 中提取数组中的实际 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
}

数组访问速度很快,单数据库列查询也很快。

于 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 回答