在控制器中安全使用多个示波器。
在控制器中,我需要调用三个范围中的一个。如何安全地做到这一点?
如果我发送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'
答案 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