Smart params matcher para Rails

Hoje eu precisava comparar os parâmetros com o conjunto de controladores aninhados e começo a sentir que meu params_match?auxiliar simples é muito simples para esse trabalho.

Nota: aqui está a essência do código. A formatação do código Coderwall é meio ruim.

# Usage:
# params_match?(controller: 'comments', article_id: 23, id: 1)
def params_match?(pattern)
return true if pattern.nil? || pattern.empty?

pattern
.collect do |(param, value)|
if value.is_a? Array
value
.map(&:to_s).include?(params[param].to_s)
else
value
.to_s == params[param].to_s
end
end.reduce(&:&)
end

Este auxiliar pesquisa simples o padrão dado e ignora o resto dos parâmetros de solicitação.

Portanto, se tivermos, por exemplo, comentários do controlador aninhados em artigos, precisamos fazer a correspondência com essas ações como esta:

params_match?(controller: 'articles', action: 'show', article_id: @article.id) || 
params_match
?(controller: 'comments', action: 'index', article_id: @article.id) ||
params_match
?(controller: 'comments', action: 'edit', article_id: @article.id, id: @comment.id) ||
params_match
?(controller: 'comments', action: 'update', article_id: @article.id, id: @comment.id)
# etc

Muito prolixo e não confortável. Ajudará se pudermos fornecer algum tipo de condição ‘OU’ para controladores, ações e parâmetros.

Vamos fazer um ajudante mais avançado:

# Usage:
# smart_params_match?([:comments], [:edit, :update], {article_id: 23, id: 1}, {:comment_id: 1})
def smart_params_match?(controllers, actions, *params_or)
return false unless controllers.nil? || controllers.empty? || [*controllers].include?(params[:controller].to_sym)
return false unless actions.nil? || actions.empty? || [*actions].include?(params[:action].to_sym)
params_or
.nil? || params_or.empty? || [*params_or].map { |pars| params_match?(pars) }.reduce(&:|)
end

E agora tentamos corresponder à mesma condição do exemplo anterior:

smart_params_match?(:articles, :show, article_id: @article.id) || 
smart_params_match
?(:comments, [:index, :edit, :update], {article_id: @article.id}, {article_id: @article.id, id: @comment.id})

Que pode ser simplificado para isto:

smart_params_match?(:articles, :show, article_id: @article.id) || 
smart_params_match
?(:comments, [], article_id: @article.id)

Ou mesmo para isso

smart_params_match?([:articles, :comments], nil, article_id: @article.id)

Observe que você pode usar de zero a muitos controladores, ações e combinações de parâmetros. O nilor []para controladores ou ações atuam como um caractere curinga. Os parâmetros são comparados apenas com as chaves e valores fornecidos (estamos reutilizando aqui). Se você precisar combinar vários padrões de parâmetro, você pode apenas outro hash de parâmetros no final da lista de argumentos. O matcher retorna verdadeiro se os parâmetros do pedido atual incluem um dos controladores fornecidos, ações e se um dos padrões de parâmetro corresponder.params_match?

Deixe-me saber se você tem alguma solução melhor para isso ou se você tem alguma melhoria no código.

Boa codificação!

<script src = ” https://gist.github.com/wojtha/2972034afdcf6796ce1a.js”> </script>