允许用户通过GET参数选择一个命名范围

时间:2009-05-17 21:20:08

标签: ruby-on-rails search scope

在我的帖子模型中,我有一个命名范围:

named_scope :random, :order => "Random()"

我想通过发送params[:scope] = 'random'的GET请求,让用户能够以随机顺序获取帖子。

缺少eval("Post.#{params[:scope]}"),我该怎么做?

5 个答案:

答案 0 :(得分:2)

我会建议我非常棒的acts_as_filter插件,用于通过named_scopes进行用户驱动的结果过滤。

http://github.com/tobyhede/acts_as_filter/tree/master

Eval可以使用 - 但请确保您对已接受/期望的值进行验证(我经常只是将一些值插入数组并测试accepted_values.include?(参数))

答案 1 :(得分:2)

eval是一个非常糟糕的主意。然而,#send非常适合这一点 - 它本身更安全,比eval更快(据我理解)。

Product.send(params[:scope])

应该这样做:)

答案 2 :(得分:1)

因为你正在处理来自用户的数据,所以我会远离eval。也许只是使用一个简单的案例陈述?这样,您就可以验证他们为您提供的数据。

答案 3 :(得分:1)

我在搜索中遇到过它。 searchlogic是完美的。

答案 4 :(得分:0)

对于您提供的示例,我将是明确的,并将链范围一起构建您想要的查询:

scope = Post
scope = scope.random if params[:scope] == 'random'
@posts = scope.find(:all, ...) # or paginate or whatever you need to do

如果params [:scope]不是'random',这与调用Post.find()相同,否则它正在执行Post.random.find()

从其他答案中,看起来find_by_filter会为你做同样的事情。

如果需要支持非互斥的内容,使用此模式,您还可以将多个范围组合到查询中 例如

scope = scope.only_monsters if params[:just_monsters] == 1    
scope = scope.limit(params[:limit].to_i) unless params[:limit].to_i.zero?

所以GETting / posts?scope = random& just_monsters = 1& limit = 5会给你:

Post.random.just_monsters.limit(5).find(:all, ...)