我正在构建一个用户可以发布的应用。每个帖子都受到赞成和投票。在显示帖子的地方,我有一个允许用户过滤帖子的小表格。它只是将一个参数传递给名为params [:post_filter]的url(localhost:3000 / somepage?post_filter = value)。现在,除了我编写的用于修改查询的私有方法不起作用之外,这个工作得很好和花花公子。
这是我的问题:
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
答案 0 :(得分: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
答案 1 :(得分:1)
尝试将数字与数字或字符串与字符串进行比较。
引用1,2和3
when '1'
...
或将chosen_options
转换为数字
答案 2 :(得分: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)
相同,可以是true
或false
。
你想要的是,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
代替魔术数字,它会帮助其他人在(非长期)未来阅读您的代码和自己:)