如果rails控制器中的else语句不起作用

时间:2015-02-21 03:53:53

标签: ruby-on-rails

我正在尝试对我的form_tag字段进行验证:如果用户未选择开始日期或结束日期,则应将其重定向到同一页面。我在我的控制器中使用'if else'语句执行此操作。但是,如果其他声明不起作用。

以下是我的控制器操作:

def dateFilter  
  cat_id = params[:Category]
  if cat_id == ''
    @expensesFiltered = current_user.expenses.where(:created_at => (params[:start_date].to_date .. params[:end_date].to_date))
  elsif params[:start_date] == ''
    redirect_to '/expenses/dateForm'
  elsif params[:end_date] == ''
    redirect_to '/expenses/dateForm'
  else
    @expensesFiltered = current_user.expenses.where(:created_at => (params[:start_date].to_date .. params[:end_date].to_date)). where("category_id = ?", cat_id[:id])
  end
  @total = @expensesFiltered.sum("amount")
end

以下是我的观点dateForm.html.erb

<%= form_tag({:controller => 'expenses', :action => 'dateFilter'}, :class =>"datepicker") do %>
<%= collection_select Category, :id, Category.all, :id, :name, :include_blank => "Please select category..." %>
<%= label_tag("Start Date") %> <br />
<%= text_field_tag(:start_date) %>
<%= label_tag("End Date") %> <br />
<%= text_field_tag(:end_date) %>
<%= submit_tag "Submit" %>
<% end %> 

它不会被重定向并出错。请建议。

如果未选择end_date,则不会给出任何方法错误,而不是if条件中给出的重定向。服务器日志如下:

Started POST "/expenses/dateFilter" for 127.0.0.1 at 2015-02-21 17:10:15 +0530
Processing by ExpensesController#dateFilter as HTML
Parameters: {"utf8"=>"✓",  "authenticity_token"=>"b9eGV7op60letvlaV/62KpAh56KSbD4bd6jhiLeulOk=", "Category"=>{"id"=>"8"}, "start_date"=>"", "end_date"=>"", "commit"=>"Submit"}
Redirected to http://localhost:3000/expenses/dateForm
Completed 500 Internal Server Error in 1ms

NoMethodError (undefined method `sum' for nil:NilClass):

app / controllers / expenses_controller.rb:50:在`dateFilter'

如果未选择类别,则不在“if cat_id =''”中执行查询,而是在else部分执行查询并且不提供任何记录。 以下是服务器日志:

Started POST "/expenses/dateFilter" for 127.0.0.1 at 2015-02-21 16:54:36 +0530
Processing by ExpensesController#dateFilter as HTML
Parameters: {"utf8"=>"✓",  "authenticity_token"=>"b9eGV7op60letvlaV/62KpAh56KSbD4bd6jhiLeulOk=", "Category"=>{"id"=>""}, "start_date"=>"2015-01-03", "end_date"=>"2015-01-05", "commit"=>"Submit"}
User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
 (0.4ms)  SELECT SUM("expenses"."amount") AS sum_id FROM "expenses" WHERE "expenses"."user_id" = ? AND ("expenses"."created_at" BETWEEN '2015-01-03' AND '2015-01-05') AND (category_id = '')  [["user_id", 1]]
Expense Load (0.4ms)  SELECT "expenses".* FROM "expenses" WHERE "expenses"."user_id" = ? AND ("expenses"."created_at" BETWEEN '2015-01-03' AND '2015-01-05') AND (category_id = '') ORDER BY created_at DESC  [["user_id", 1]]
Rendered collection (0.0ms)
Rendered expenses/dateFilter.html.erb within layouts/application (36.2ms)
Rendered layouts/_shim.html.erb (0.5ms)
Rendered layouts/_header.html.erb (1.7ms)
Completed 200 OK in 1120ms (Views: 945.1ms | ActiveRecord: 1.9ms)

2 个答案:

答案 0 :(得分:0)

不能直接回答您的问题,但我建议您使用scopes。如果参数存在与否,它们已经内置支持测试,并遵循“瘦控制器,脂肪模型”的理念。像这样:

控制器

@expensesFiltered = current_user.expenses.date_filter(params[:start_date], params[:end_date]).category_filter(params[:category])

模型

scope :date_filter, -> (start_date, end_date) { where (:created_at =>  (start_date.to_date .. end_date.to_date)) if start_date.present? and end_date.present? } 

scope :category_filter, -> (category) { where ("category_id = ?", category) if category.present? }

答案 1 :(得分:0)

我的猜测是redirect_to没有退出dateFilter方法,所以

  @total = @expensesFiltered.sum("amount")
无论条件如何,

都会被执行。如果是这种情况,您应该可以通过向return块添加elseif语句来解决此问题

  # [...]
  elsif params[:start_date] == ''
    redirect_to '/expenses/dateForm'
    return
  elsif params[:end_date] == ''
    redirect_to '/expenses/dateForm'
    return
  else
  # [...]
@total的计算移动到else块中,

  # [...]
  else
    @expensesFiltered = current_user.expenses.where(:created_at => (params[:start_date].to_date .. params[:end_date].to_date)). where("category_id = ?", cat_id[:id])
    @total = @expensesFiltered.sum("amount")
  end
  # [...]

这应该至少摆脱nil:NilClass的错误NoMethodError (undefined method和'。它是否也会使重定向工作,我不知道。