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() 値をプライベート メソッドの文字列の 1 つに置き換えると、すべてが計画どおりに機能します。ただし、プライベート メソッド名を .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)のいずれ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マジック ナンバーの代わりに使用することを検討してください。これは、他の人があなたのコードとあなた自身を (長くない) 将来的に読むのに役立ちます :)

于 2012-08-15T13:30:10.183 に答える