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 nil
or []
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>