Ruby on Rails 通过acts_as_taggable_on_steroids 随机发布
使用 Rails 3,我是 RoR 菜鸟,所以这可能很简单,但我似乎无法弄清楚。我的意思是,我可以让它工作,但我无法找出最好的方法。
好的,我已经阅读了关于通过 Rails 选择随机记录的每个问题,我认为答案在很大程度上是非常简单的。但是,我被迫在选择随机记录之前调用 acts_as_taggable_on_steroids 方法,因此我的首选技术不起作用,因为 find_tagged_with 返回一个数组。
这是一个由两部分组成的问题。从性能的角度来看,我需要知道哪种方法是最好的,以及如果使用不同的 tag.name 多次调用此方法,如何防止结果中出现重复的帖子。
以下是我到目前为止尝试过的方法:
def related_posts(tag)
rand_id = rand(Post.find_tagged_with(tag.name).count)
rand_record = Post.find_tagged_with(tag.name, :conditions => [ "posts.id >= ?", rand_id], :limit => 2)
end
def related_posts(tag)
rand_id = rand(Post.find_tagged_with(tag.name).count)
post = Post.find_tagged_with(tag.name, :offset => rand_id, :limit => 2)
end
def related_posts(tag)
post = Post.find_tagged_with(tag.name, :order => 'RAND()', :limit => 2)
end
def related_posts(tag)
posts = Post.find_tagged_with(tag.name)
offset = rand(posts.count)
posts.find(:offset =>offset) #doesn't work since this is an array at this point :(
end
def related_posts(tag)
related = []
posts = Post.find_tagged_with(tag.name)
related << random_post(posts)
related << random_post(posts)
return related
end
def random_post(obj)
rand_id = rand(obj.count)
rand_record = obj[rand_id]
end
编辑:这似乎是最快的,尽管我对 Rails 应用程序的性能测试经验很少。
def related_posts(tag)
posts = Post.find_tagged_with(tag.name).sort_by { rand }.slice(0, 2)
end
无论谁碰巧回答了这个问题,您能否也解释一下究竟发生了什么?是在数据库级别随机化记录并排序还是其他什么。另外,这对于 Rails 应用程序的性能通常意味着什么?
Using Rails 3, and I'm a RoR noob, so this might be simple, but I can't seem to figure it out. What I mean is, I can get it to work, but I can't figure out the best way.
Ok, I've read every question on SO about selecting random records via Rails, and I think the answer is pretty straight forward, for the most part. However, I'm forced to call an acts_as_taggable_on_steroids method before selecting a random record, so my preferred technique doesn't work, since find_tagged_with returns an array.
This is a two-part question. I need to know which of these methods are the best, from a performance standpoint, and also how to prevent duplicate posts from being in the results if this method is called more than once with a different tag.name.
Here are the ways I've tried so far:
def related_posts(tag)
rand_id = rand(Post.find_tagged_with(tag.name).count)
rand_record = Post.find_tagged_with(tag.name, :conditions => [ "posts.id >= ?", rand_id], :limit => 2)
end
def related_posts(tag)
rand_id = rand(Post.find_tagged_with(tag.name).count)
post = Post.find_tagged_with(tag.name, :offset => rand_id, :limit => 2)
end
def related_posts(tag)
post = Post.find_tagged_with(tag.name, :order => 'RAND()', :limit => 2)
end
def related_posts(tag)
posts = Post.find_tagged_with(tag.name)
offset = rand(posts.count)
posts.find(:offset =>offset) #doesn't work since this is an array at this point :(
end
def related_posts(tag)
related = []
posts = Post.find_tagged_with(tag.name)
related << random_post(posts)
related << random_post(posts)
return related
end
def random_post(obj)
rand_id = rand(obj.count)
rand_record = obj[rand_id]
end
Edit: This seems to be the fastest, although I have very little experience performance testing rails apps.
def related_posts(tag)
posts = Post.find_tagged_with(tag.name).sort_by { rand }.slice(0, 2)
end
Whoever happens to answer this question, could you also please explain what exactly is happening? Is it randomising the records and sorting on the database level or something else. Also, what does that typically mean performance-wise with a rails app?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将为您分解这一行:
对 find_tagged_with 的第一个链式调用设置 SQL 并执行查询。我想它是一个 ActiveRecord::Relation 对象。
第二个 sort_by 是一个内置的 Rails 方法。所以它不使用数据库来进行排序。如果您在第一次调用中提取了数万条记录,这可能会变得昂贵。更多信息请参见:http://paulsturgess。 co.uk/articles/show/85-ruby-on-rails-sort_by-vs-sort
最后,slice(0, 2) 是一个数组方法,分割结果数组。还有很多其他方法可以做到这一点,例如 .first( 2 ) 或 [0..2]
另外,这里有一份详细的 Ruby on Rails 基准测试指南(性能测试每种方法):http://guides.rubyonrails.org/performance_testing.html
I'll break this line down for ya:
The first chained call to find_tagged_with sets up the SQL and performs the query. I imagine it's an ActiveRecord::Relation object.
The second, sort_by is a built-in Rails method. So it's not using the database to do the sorting. This could become pricey if you have tens of thousands of records pulled in the first call. More on this here: http://paulsturgess.co.uk/articles/show/85-ruby-on-rails-sort_by-vs-sort
Lastly, the slice(0, 2) is an Array method, cutting up your array of results. There's tons of other ways of doing this, such as .first( 2 ) or [0..2]
Also, here's a detailed Ruby on Rails guide to benchmarking (performance testing each method): http://guides.rubyonrails.org/performance_testing.html