Rails 4 - 动态范围

时间:2015-06-17 15:12:18

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

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

模型: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"

Controller: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 个答案:

答案 0 :(得分: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

然后在我的视图中(使用我编写的简单助手将其显示为Bootstrap 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"