问题
At the end of a blog post I would like to display a teaser link to another random post. Obviously this link should be NOT a teaser for the current post itself.
I figured already out how to choose a random post, but there is still the chance that the teaser link is a link to the current post. I couldn't figure out, how can I exclude this case.
Here is my controller:
def show
@post = Post.find(params[:id])
@staff_pickrandom = Post.where(staff_pick:true).order("RANDOM()").limit(1)
end
I am quite new to Rails and I am still struggling with basic stuff. Sorry, if this is an easy one. Thank you so much for helping out!!!
UPDATE: I am using Rails 3.2 and the "friendly_id" Gem.
回答1:
Using order('RANDOM()').limit(1)
is the right way to start since it is better to let the DB choose a random record, than fetching a large set of ids, and letting Ruby sample from an array. In order to avoid choosing the post you are currently on use where.not
to exclude that post
Post.where(staff_pick: true).where.not(id: @post.id).order('RANDOM()').limit(1)
or
Post.where(staff_pick: true).where('id != ?', @post.id).order('RANDOM()').limit(1)
回答2:
It depends on how large you want the set to be. The easiest is:
@staff_pickrandom = Post.where(staff_pick:true).sample
That will pick a random object from the array returned by Post.where(staff_pick:true)
. If you find that is too many records then you can add more into the where clauses
回答3:
def show
@post = Post.find(params[:id]) # [1]
ids = Post.ids # [1, 2, 3, 4, 5]
ids.shuffle # [3, 5, 2, 1, 4]
ids.delete(params[:id]) # [3, 5, 2, 4]
@staff_pickrandom = Post.find(ids[0]) # [3]
end
there is many way to do that. It's better to create a helper.
回答4:
Try:
@post = Post.where(staff_pick: true).where.not(id: params[:id]).shuffle.first
If where.not
can't be done like in Rails 4, try:
Post.where(staff_pick: true).where("id != ?", params[:id]).shuffle.first
Edit: since you're using friendly_id gem, you shouldn't compare the slug (params[:id]) to a recorded id in database.
First declare which post you're looking for like @post = Post.find(params[:id])
and remove params[:id] from the queries above and use @post.id
instead.
I guess that should work!
来源:https://stackoverflow.com/questions/21836885/rails-show-a-random-record-but-not-the-current