Wywołanie metody zapisanej w stringu

Cześć,

Mam w widoku takie coś.

<% case params[:category_service] %>
<% when 'a' %>
  <% if policy(@certificate).show_a? %>
    ....    
  <% end %>
<% when 'b' %>
  <% if policy(@certificate).show_b? %>
    ...
  <% end %>
<% when 'c' %>
  <% if policy(@certificate).show_c? %>
    ...
  <% end %>
<% end  %> 

Powyższe działa ale jest “rzeźbą”

Chciałbym to przebudować jakoś na kształt

<% if "policy(@certificate).show_#{params[:category_service]}?" %>
  ...
<% end %>

Gdy zrobiłem:

<% if method("policy(@certificate).show_#{params[:category_service]}?") %>
  ...
<% end %>

to dostaję komunikat:

NameError - undefined method policy(@certificate).show_a?' for class#Class:0xc1b6910’:
() home/bodzio/www/netpar/app/views/certificates/_scan_and_print.html.erb:18:in _app_views_certificates__scan_and_print_html_erb___990887094_99626270' actionview (4.2.3) lib/action_view/template.rb:145:inblock in render’

Rozumiem przez to, że “method()” szuka metody “policy(@certificate).show_a?” tylko w swojej klasie.
Jak pokazać, by szukał to w module Pundit?

A może inaczej da się wywołać metodę wpisaną w string: "policy(@certificate).show_#{params[:category_service]}?"


Help me, please!

Proponuje przenieść ten fragment do helpera i robić to helperze, który zwróci ci daną wartość.

module PolicyHelper
  def show(certificate, category_service)
    unless ['a', 'b', 'c'].include?(category_service)
       raise "Ruby injection"
    end
    policy(certificate).send('show_#{category_service}?')
  end
end

i wtedy w widoku coś takiego

<% if show(certificate, params[:category_service]) %>
...
<% end %>

Nie jestem pewny tylko czy powinno się stosować wyjątki w Helperach. Jeśli ktoś będzie chciał podmienić parametr i dokonać ataku to taki wyjątek zostanie zaraportowany a gość powinien zobaczyć 404, ew. można zamienić unless na if i wykonywać operację w if’ie, a w przypadku gdy nie znajduje się w tablicy zwracać nil.

1 Like

Dzięki za pomoc!

Działa świetnie! :slight_smile: