在控制器中安全使用多个示波器

时间:2014-04-17 13:30:44

标签: ruby-on-rails ruby-on-rails-4

在控制器中安全使用多个示波器。

在控制器中,我需要调用三个范围中的一个。如何安全地做到这一点?

如果我发送params scope=destroy_all,则会删除所有条目。

控制器中的方法:

def index
  @campaigns = Campaign.send(params[:scope] || 'all')
end

的范围:

scope :ended, -> {where ("date(current_timestamp) - date(created_at) > ends_at")}
scope :active, -> {where ("date(current_timestamp) - date(created_at) < ends_at")}

观点:

.btn-group
  = link_to _('Ended Campaigns'), admin_campaigns_path(scope: :ended), class: 'btn btn-default'
  = link_to _('Ob-going Campaigns'), admin_campaigns_path(scope: :active), class: 'btn btn-default'
  = link_to _('All Campaigns'), admin_campaigns_path(scope: :all), class: 'btn btn-default'

3 个答案:

答案 0 :(得分:2)

这是一个过滤前的

class YourController
  before_filter :filter_scopes, only: :index

  def index
    @campaigns = Campaign.send(params[:scope] || 'all')
  end

  private
  def filter_scopes
    params[:scope] = nil unless ['ended','active'].include?(params[:scope])
  end
end

通过这种方式,您确信只有&#34;结束&#34;,&#34;活跃&#34;和#34;所有&#34;是调用范围时允许的值

编辑:这是一个陈旧的答案,我想补充说before_filter已在新的rails版本上替换为before_action。此外,我现在认为,如果没有before_action并且不更改params哈希,可能会有一个更优雅的解决方案,只需添加一个&#34; getter&#34;对于范围值:

class YourController
  def index
    @campaigns = Campaign.send(get_scope_from_params)
  end

  def get_scope_from_params
    ['ended','active'].include?(params[:scope]) ? params[:scope] : 'all'
  end
end

如果需要在视图上使用它,您甚至可以将其作为辅助方法。我认为最好不要修改params hash(除非你确定这是你想要的),并且更有意义的是拥有一个&#34; getter&#34;方法而不是before_action方法,因为您实际需要的是获取有效的范围名称。

答案 1 :(得分:1)

您可以将示波器列入白名单,例如:

@campaigns = if %w(ended active).include?(params[:scope])
               Campaign.public_send(params[:scope])
             else
               Campaign.all
             end

答案 2 :(得分:0)

我认为将范围应用程序留给用户输入是太不安全和神秘。

我会这样做

def index
  @campaigns = Campaign.all
  if params[:scope] == 'ended'
    @campaign = @campaign.ended
  elsif params[:scope] == 'active'
    @campaign = @campaign.active
  end
end