3

これが私が持っているものです

現在、私はこれをやっています:

current_account.send(object).search(params[:search]).user_id_equals_any(users).visibility_is_any(visibilities)

しかし、それは非常に柔軟ではありませんか?これらのスコープのいずれかを条件付きで持たないようにしたい場合はどうすればよいですか?

条件付きで追加された要素を持つスコープの配列が良い解決策になると思います

.send() を使用して呼び出すパラメーターの配列

scopes = []    
scopes = << [:user_id_equals_any, users] if filter_users
    scopes = << [:visibility_is_any, visibilities] if filter_visibility

そのため、不明な番号スコープがいくつかある可能性があります。

スコープを実行するには、呼び出す必要があります.send(:scope_name, scope_param)

scopesしかし、配列内の任意の数のスコープに対してそれを行うにはどうすればよいですか?

ループとしては、次のようなものになると思います

result = current_account.send(object).search(params[:search])
scopes.each do |scope|
    result.send(scope[0], scope[1])
end
return result

ループは次のように単純化できます

scopes.each {|s| result.send(s[0], s[1]) }

しかし、異なる送信呼び出しを 1 行に追加する方法はありますか?

4

2 に答える 2

3

使用できますinject

scopes = []
# Note that in your example, the assignment is invalid syntax
scopes << [:user_id_equals_any, users] if filter_users
scopes << [:visibility_is_any, visibilities] if filter_visibility

# initial result
result = current_account.send(object).search(params[:search])

# applying the scopes
result = scopes.inject(result) do |result, (method, param)|
  result.send(method, param)
end
return result

各ループでは、前のブロック実行の最後の戻り値が、ブロックの最初のパラメーター (この場合は ) に渡されますresult。最初のループは最初の結果を取得します (つまり、inject呼び出しに対する角括弧内のパラメーター。最後のループの戻り値が返されます。

詳細については、ドキュメントをご覧ください。

于 2012-06-15T19:38:25.007 に答える
1

自由に独自の抽象化を構築して、問題に対する考え方をコードに反映させてください。

class Object
  def send_if(condition, *args, &block)
    condition ? send(*args, &block) : self
  end
end

current_account.send(object).search(params[:search]).
  send_if(filter_user, :user_id_equals_any, users).
  send_if(filter_visibility, :visibility_is_any, visibilities)
于 2012-06-15T20:34:30.360 に答える