2015-06-17 83 views
4

我有一个应用程序,用户可以在其中定义自己的“状态”。然后我创建一个动态范围来处理这个问题。这在当地工作非常好,但是当我推到Heroku时,它不是因为某种原因。Rails 4 - 动态范围

型号:Task.rb:

Status.all.each do |status| 
    scope "#{status.name}".downcase.delete(' '), -> { where('status_id = ?', status.id).order('created_at DESC') } 
    end 

路线:routes.rb中:

get 'tasks/filters/status/:scope' => "tasks#index" 

控制器:tasks_controller.rb:

在这种情况下,关于状态的用户点击从视图上看,它落入else区块并运行if params[:scope]部分并执行@tasks = Task.send(params[:scope])

def index 
    @statuses = Status.all.order('name') 
    if params[:tag] 
     @tasks = Task.tagged_with(params[:tag]) 
    else 
     if params[:scope] 
     @tasks = Task.send(params[:scope]) 
     elsif params[:showall] 
     @tasks = Task.all.order('created_at DESC') 
     else 
     @tasks = Task.all.where('assigned_to = ?', current_user).order('created_at DESC'). 
      reject { |t| t.status.default_view != true } 
     end 
    end 
    end 

正如我所说的,当我使用rails s在本地运行时,此功能完美,但当我推到Heroku时,出现错误。运行heroku logs揭示了这一点:

2015-06-17T15:06:07.769748+00:00 app[web.1]: Parameters: {"scope"=>"open"} 
2015-06-17T15:06:07.895996+00:00 app[web.1]: Role Load (1.4ms) SELECT "public"."roles".* FROM "public"."roles" WHERE "public"."roles"."id" = $1 LIMIT 1 [["id", 1]] 
2015-06-17T15:06:07.907046+00:00 app[web.1]: ArgumentError (wrong number of arguments (0 for 1+)): 
2015-06-17T15:06:07.907043+00:00 app[web.1]: 
2015-06-17T15:06:07.907050+00:00 app[web.1]: 
2015-06-17T15:06:07.907048+00:00 app[web.1]: app/controllers/tasks_controller.rb:12:in `index' 
2015-06-17T15:06:07.907049+00:00 app[web.1]: 
2015-06-17T15:06:07.972702+00:00 app[web.1]: Started GET "/tasks/filters/status/open" for 173.27.229.45 at 2015-06-17 15:06:07 +0000 
2015-06-17T15:06:07.998359+00:00 app[web.1]: Completed 500 Internal Server Error in 23ms 

凡tasks_controller.rb线12:

@tasks = Task.send(params[:scope]) 

是怎么回事?它说ArgumentError (wrong number of arguments (0 for 1+)),但第一个条目清楚地表明参数“范围”正在设置正确(在这种情况下“打开”)。

+1

我不认为通过'PARAMS [:范围]''来是Task.send'这样一个伟大的想法。如果有人将'scope'设置为'destroy_all'或其他破坏性会发生什么? – PerfectlyNormal

+0

@PerfectlyNormal - 赶上!我没有考虑到这一点。看起来我不得不想另一种方式来支持这个功能。 – Trinculo

+0

@PerfectlyNormal - 或者可能只是限制用户创建任何是任务的方法或instance_method的东西?这还不好吗? – Trinculo

回答

2

尽管我不确定它为什么在开发中起作用,但不是生产,正如@PerfectlyNormal所指出的那样,我这样做的方式存在安全风险。

我想我过度思考如何做到这一点。我想出了这个方式,它似乎做工精细:

def index 
    @statuses = Status.all.order('name') 
    @priorities = Priority.all.order('name') 
    @products = Product.all.order('name') 
    if params[:status_id] 
     @tasks = Task.all.where("status_id = ?", params[:status_id]) 
    elsif params[:priority_id] 
     @tasks = Task.all.where("priority_id = ?", params[:priority_id]) 
    elsif params[:product_id] 
     @tasks = Task.all.where("product_id = ?", params[:product_id]) 
    elsif params[:tag] 
     @tasks = Task.tagged_with(params[:tag]) 
    elsif params[:all_tasks] 
     @tasks = Task.all 
    else 
     @tasks = Task.all 
    end 
    end 

然后在我的观点(即用简单的助手,我写来显示它作为一个引导3标签根据颜色用户选择):

  <% @statuses.all.each do |status| %> 
      <%= link_to "/tasks/filters/status/#{status.id}" do %> 
       <%= filter_status(status) %> 
      <% end %> 
      <% end %> 

最后,在我的routes.rb

get 'tasks/filters/status/:status_id' => "tasks#index" 
get 'tasks/filters/priority/:priority_id' => "tasks#index" 
get 'tasks/filters/product/:product_id' => "tasks#index"