Ruby on Rails:提取SQL返回错误

时间:2015-07-23 05:38:26

标签: ruby-on-rails ruby sql-server postgresql

我正在营销销售管理数据库。

要计算每个月的销售摘要,我编写了控制器方法,该方法由HTML POST请求触发。

它的工作方式是将订单分成不同月份的组。首先是检查数据库中的年份是否已存在,然后是月份。如果该月份已经存在于数据表中,请更新其属性,如果没有创建具有新月份的新数据对象。

计算每个月的total_cost,收入。

然后记录将保存到我的数据库中。

def generate_report
  @orders_by_month = current_user.orders.all.group_by { |order| order.order_date.beginning_of_month }

  @orders_by_month.each do |month, orders|
    if current_user.data.where("extract(year from month_record) = ?", month.strftime('%Y').to_i).present?
      this_year = current_user.data.where("extract(year from month_record) = ?", month.strftime('%Y').to_i)
      if this_year.where("extract(month from month_record) = ?", month.strftime('%m').to_i).present?
        @report = this_year.where("extract(month from month_record) = ?", month.strftime('%m').to_i).first
      end
    else
      @report = Datum.new
    end
    vnd = orders.first.vnd.to_f
    total_cost = (orders.map(&:total_cost).sum.to_f / vnd).round(2)
    selling = (orders.map(&:selling_price).sum.to_f / vnd).round(2)
    count = orders.count

    @report.month_record = month
    @report.total_cost = total_cost
    @report.total_selling = selling
    @report.revenue = (selling - total_cost).round(2)
    @report.order_sold = count
    @report.user_id = current_user.id

    @report.save

    orders.each do |order|
      order.update_attributes(datum_id: @report.id)
    end
end

    redirect_to user_report_path(current_user)
end

路由没有问题。我的开发和生产(Heroku)都使用Postgresql

如果您有兴趣,这是我的宝石文件:

source 'https://rubygems.org'

gem 'rails', '4.2.0'
gem 'bootstrap-sass', '~> 3.3.5'
gem 'sass-rails', '~> 5.0'
gem 'bootstrap_form'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'turbolinks'
#gem 'pjax_rails'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc

gem 'bcrypt', '~> 3.1.7'
gem 'jquery-turbolinks'

gem 'carrierwave',             '0.10.0'
gem 'mini_magick',             '3.8.0'
gem 'fog',                     '1.23.0'

gem 'bootstrap-datepicker-rails'

gem 'goog_currency'
gem 'whenever', :require => false
gem 'public_activity'
gem 'pg'

group :development, :test do
  gem 'byebug'
  gem 'web-console', '~> 2.0'
  gem 'spring'
end

group :production do
  gem 'rails_12factor'
end

请注意,在我的开发中,一切都运行良好。但是,我从heroku日志中得到了这个错误:

User Load (1.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
2015-07-23T05:02:39.250745+00:00 app[web.1]: Started POST "/users/1/report" for 123.16.255.248 at 2015-07-23 05:02:39 +0000
2015-07-23T05:02:39.268004+00:00 app[web.1]:   Datum Load (1.3ms)  SELECT "data".* FROM "data" WHERE "data"."user_id" = $1 AND (extract(year from month_record) = 2015)  [["user_id", 1]]
2015-07-23T05:02:39.270829+00:00 app[web.1]: Completed 500 Internal Server Error in 18ms
2015-07-23T05:02:39.252943+00:00 app[web.1]:   Parameters: {"authenticity_token"=>"pB0Aqc9oRumYxCgoIzeoGEDJqsyQLRiUCYI7QTHVCmuBfPpaSdXmuHUO6oauTzIi2SsbrB5zhUywSGgw5YPNhw==", "user_id"=>"1"}
2015-07-23T05:02:39.254935+00:00 app[web.1]:   User Load (1.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
2015-07-23T05:02:39.260848+00:00 app[web.1]:   Order Load (3.3ms)  SELECT "orders".* FROM "orders" WHERE "orders"."user_id" = $1  [["user_id", 1]]
2015-07-23T05:02:39.269970+00:00 app[web.1]:   Datum Load (1.1ms)  SELECT "data".* FROM "data" WHERE "data"."user_id" = $1 AND (extract(year from month_record) = 2015) AND (extract(month from month_record) = 6)  [["user_id", 1]]
2015-07-23T05:02:39.271916+00:00 app[web.1]: NoMethodError (undefined method `month_record=' for nil:NilClass):
2015-07-23T05:02:39.252920+00:00 app[web.1]: Processing by ReportsController#generate_report as HTML
2015-07-23T05:02:39.271914+00:00 app[web.1]: 
2015-07-23T05:02:39.271918+00:00 app[web.1]:   app/controllers/reports_controller.rb:31:in `block in generate_report'
2015-07-23T05:02:39.271921+00:00 app[web.1]:   app/controllers/reports_controller.rb:17:in `generate_report'
2015-07-23T05:02:39.271920+00:00 app[web.1]:   app/controllers/reports_controller.rb:17:in `each'
2015-07-23T05:02:39.271923+00:00 app[web.1]: 
2015-07-23T05:02:39.271924+00:00 app[web.1]: 
2015-07-23T05:02:39.273133+00:00 heroku[router]: at=info method=POST path="/users/1/report" host=red-moose-2689.herokuapp.com request_id=d4cdd0fa-739d-48f9-87ce-eae4a597

与development.log比较:

Started POST "/users/1/report" for ::1 at 2015-07-23 11:19:04 +0700
Processing by ReportsController#generate_report as HTML
Parameters:         {"authenticity_token"=>"WFrVOTwDrTg7sZLhz+RkLOeKUYXixjddEDuhkUrzxWYerG9F9KPz3DWNTagbhbAMPLU0xpQNd805UDIjO3w+uA==", "user_id"=>"1"}
[1m[35mUser Load (0.3ms)[0m  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
[1m[36mUser Load (0.2ms)[0m  [1mSELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1[0m  [["id", 1]]
[1m[35mOrder Load (1.5ms)[0m  SELECT "orders".* FROM "orders" WHERE "orders"."user_id" = $1  [["user_id", 1]]
[1m[36mDatum Load (0.6ms)[0m  [1mSELECT "data".* FROM "data" WHERE "data"."user_id" = $1 AND (extract(year from month_record) = 2016)[0m  [["user_id", 1]]
[1m[35mDatum Load (0.8ms)[0m  SELECT "data".* FROM "data" WHERE "data"."user_id" = $1 AND (extract(year from month_record) = 2016) AND (extract(month from month_record) = 7)  [["user_id", 1]]
[1m[36mDatum Load (0.9ms)[0m  [1mSELECT  "data".* FROM "data" WHERE "data"."user_id" = $1 AND (extract(year from month_record) = 2016) AND (extract(month from month_record) = 7)  ORDER BY "data"."id" ASC LIMIT 1[0m  [["user_id", 1]]
[1m[35m (0.2ms)[0m  BEGIN
[1m[36mSQL (0.5ms)[0m  [1mUPDATE "data" SET "revenue" = $1, "updated_at" = $2 WHERE "data"."id" = $3[0m  [["revenue", "-525.710000000000036379788070917129516602"], ["updated_at", "2015-07-23 04:19:04.938382"], ["id", 5]]
[1m[35m (1.0ms)[0m  COMMIT

抱歉,我的英语不好。我希望你能理解我的问题。我在这里走到了尽头。我感谢任何帮助。

更新

该项目的Github回购:https://github.com/LongPotato/Gotato

reports_controllers.rb

在嵌套month条件下查找存在if时出现错误,有些错误会绕过检查条件并将nil对象返回@report

1 个答案:

答案 0 :(得分:0)

修复问题:

在第二个else之后添加if子句,以防止将nil分配给@report

def generate_report
@orders_by_month = current_user.orders.all.group_by { |order| order.order_date.beginning_of_month }

  @orders_by_month.each do |month, orders|
  if current_user.data.where("extract(year from month_record) = ?", month.strftime('%Y').to_i).present?
    this_year = current_user.data.where("extract(year from month_record) = ?", month.strftime('%Y').to_i)
    if this_year.where("extract(month from month_record) = ?", month.strftime('%m').to_i).present?
      @report = this_year.where("extract(month from month_record) = ?", month.strftime('%m').to_i).first
    else
      @report = Datum.new
    end
  else
    @report = Datum.new
  end
  vnd = orders.first.vnd.to_f
  total_cost = (orders.map(&:total_cost).sum.to_f / vnd).round(2)
 .
 .
 .
end
end