0

我正在构建一个用户可以发布的应用程序。每个帖子都被赞成和反对。在显示帖子的地方,我有一个允许用户过滤帖子的小表单。它只是将一个参数传递给名为 params[:post_filter] (localhost:3000/somepage?post_filter=value) 的 url。现在,这工作得很好,很花哨,除了我写的修改查询的私有方法不起作用。

这是我的查询:

def room
            @posts = Post.where('lesson_id = ?', params[:id]).order(post_filter_params).page(params[:page]).per(30)
    end

这是我的私人方法:

private

def post_filter_params
    chosen_option = params[:post_filter].to_i == 1 or 2 or 3 ? params[:post_filter] : '1'
    case chosen_option
    when 1
        'created_at DESC'
    when 2
        'upvotes DESC'
    when 3
        'downvotes DESC'
    end
end

现在,每当我用我的私有方法中的一个字符串替换 .order() 值时,一切都按计划进行。但是,将私有方法名称放在 .order() 值中不起作用。关于发生了什么的任何想法?

编辑

为了确保所有值都是相同的数据类型,我这样做了,但它仍然不起作用:

def post_filter_params
    param_option = params[:post_filter].to_i
    chosen_option = param_option == 1 or 2 or 3 ? param_option : 1
    case chosen_option
    when 1
        'created_at DESC'
    when 2
        '(upvotes - downvotes) DESC'
    when 3
        'downvotes DESC'
    end
end
4

3 回答 3

2

我认为私有方法不会像您认为的那样做。

这个怎么样?

def post_filter_params
  case params[:post_filter].to_i
  when 1
    'created_at DESC'
  when 2
    'upvotes DESC'
  when 3
    'downvotes DESC'
  else
    'created_at DESC'
  end
end
于 2012-08-15T11:54:33.383 回答
1

尝试将数字与数字或字符串与字符串进行比较。

引用 1、2 和 3

when '1'
...

或转换chosen_options为数字

于 2012-08-15T11:46:56.130 回答
0

我想解释@shioyama 的观点。首先,让我们关注这段代码:

param_option = params[:post_filter].to_i
chosen_option = param_option == 1 or 2 or 3 ? param_option : 1

在 IRB 会话中..

irb(main):005:0> param_option = 1
=> 1
irb(main):006:0> chosen_option = param_option == 1 or 2 or 3 ? param_option : 1
=> true
irb(main):007:0> chosen_option
=> true
irb(main):008:0> param_option = 2
=> 2
irb(main):009:0> chosen_option = param_option == 1 or 2 or 3 ? param_option : 1
=> 2
irb(main):010:0> chosen_option
=> false

因此,该行chosen_option = param_option == 1 or 2 or 3 ? param_option : 1与 相同chosen_option = (param_option == 1) or (2) or (3 ? param_option : 1),即为truefalse

你想要的是,可能是:chosen_option = param_option == 1 || param_option == 2 || param_option == 3 ? param_option : 1.

irb(main):036:0> chosen_option = param_option == 1 || param_option == 2 || param_option == 3 ? param_option : 1
=> 3
irb(main):037:0> chosen_option
=> 3

一个常见的快捷方式是chosen_option = [1, 2, 3].include?(param_option) ? param_option : 1. 但在这种情况下,最好的方法是@shioyama 建议:

def post_filter_params
  case params[:post_filter].to_i
  when 2
    'upvotes DESC'
  when 3
    'downvotes DESC'
  # you can just fallback to else
  # when 1
  #   'created_at DESC'
  else
    'created_at DESC'
  end
end

最后一个提示:考虑使用CONSTANTS而不是幻数,它将帮助其他人在(不长的)未来阅读您的代码和您自己:)

于 2012-08-15T13:30:10.183 回答