Rails调查计算结果并将结果存储在DB中

时间:2018-04-11 17:21:25

标签: ruby-on-rails database activerecord

我的调查控制器(Waterusage)出现问题。它从表单中收集了30多个变量,这些输入需要保存到waterusage db并用于计算最终得分,也保存在数据库中。

class Waterusage < ApplicationRecord
  belongs_to :user
end


class WaterusagesController < ApplicationController

  def new
    @waterusage = Waterusage.new
  end

  def create
    @user = User.find(params[:user_id])
    _showerTotal = :average_shower * :shower_flow_rate * :household_size
    _bathTotal = :bath_rate * :bath_multiplier * 35
    _bathroomSinkTotal = :bathroom_sink_usage * :bathroom_sink_flow_rate * :household_size
    _toiletTotal = :mellow * :low_flow_toilet * :household_size
    _kitchenTotal = :kitchen_sink_usage * :kitchen_sink_flow_rate
    _dishwashingTotal = :dishwasher_rate * :dishwasher_multiplier * :dishwasher_method
    _laundryTotal = :laundry_rate * :laundry_method * :laundry_multiplier
    _homeUsage = _showerTotal + _bathTotal + _bathroomSinkTotal + _toiletTotal + _kitchenTotal + _dishwashingTotal + _laundryTotal + :greywater
    _lawnTotal = :lawn_rate * :lawn_multiplier * :lawn_size * :xeriscaping
    _swimmingTotal = (:swimming_pool / 365) + (:swimming_months * 1000 / 365
    _carwashTotal = :carwash_rate * :carwash_multiplier * :carwash_method
    _outsideUsage = _lawnTotal + _swimmingTotal + _carwashTotal
    _drivingTotal = 0.735 * :miles
    _powerTotal = :statewater * :percent_statewater / 100
    _indirectTotal = :shopping + :paper_recycling + :plastic_recycling + :can_recycling + :textile_recycling + :diet + (200 * :pet_cost / 30)
    :household_total = _homeUsage + _outsideUsage + _drivingTotal + _powerTotal + _indirectTotal
    :individual_total = :household_total / :household_size
    @waterusage = @user.waterusage.create(waterusage_params)
    redirect_to user_path(@user)
  end

  def destroy
    @user = User.find(params[:user_id])
    @waterusage = @user.waterusage.find(params[:id])
    @waterusage.destroy
    redirect_to user_path(@user)
  end

  private
    def waterusage_params
      params.require(:waterusage).permit(:household_size, :average_shower,
        :shower_flow_rate, :bath_rate, :bath_multiplier, :bathroom_sink_usage,
        :bathroom_sink_flow_rate, :mellow, :low_flow_toilet, :kitchen_sink_usage,
        :kitchen_sink_flow_rate, :dishwasher_rate, :dishwasher_multiplier,
        :dishwasher_method, :laundry_rate, :laundry_multiplier, :laundry_method,
        :greywater, :lawn_rate, :lawn_multiplier, :lawn_size, :xeriscaping,
        :swimming_pool, :swimming_months, :carwash_rate, :carwash_multiplier,
        :carwash_method, :miles, :statewater, :percent_statewater, :shopping,
        :paper_recycling, :plastic_recycling, :can_recycling, :textile_recycling,
        :diet, :pet_cost, :individual_total, :household_total)
    end
end

我有更好的方法吗?目前,在用于求和小计的行上存在错误。 (即:household_total = _homeUsage + _outsideUsage + _drivingTotal + _powerTotal + _indirectTotal ) 此外,我不确定我是否正确地将用户信息连接到调查架构

2 个答案:

答案 0 :(得分:1)

你不想在控制器中做那个数学运算。瘦的控制器,脂肪模型。除此之外,它失败的一个原因是语法不正确。符号(:hello_world)不能赋值,也不能包含值。不太重要的是,虽然使用下划线前缀局部变量并不违法,但这不是Ruby中的惯例。也没有camelcase。你想要hello_world而不是helloWorld。总之...

假设:您要求必须保留总计。它们不能是计算值。

您想将这些计算移动到模型中。而不是分配大量的变量,使用方法。这样你就可以轻松地对它们进行单元测试

此处缺少的内容:模型中的验证可确保存在所有预期的属性值。控制器也应该在创建时处理无效的Waterusage实例。此代码未经测试,仅用于说明目的。

class Waterusage < ApplicationRecord
  belongs_to user

  before_validation :calculate_totals

  def calculate_totals
    self.household_total = get_household_total
    self.individual_total = get_individual_total
  end

  def get_household_total
    home_usage + outside_usage + driving_total + power_total + indirect_total
  end

  def get_individual_total
    household_total / household_size
  end

  def home_usage
    shower_total + bath_total + bathroom_sink_total + toilet_total + kitchen_total + dishwashing_total + laundry_total + greywater
  end

  def outside_usage
    lawn_total + swimming_total + carwash_total
  end

  def driving_total
    0.735 * miles
  end

  def power_total
    statewater * percent_statewater / 100
  end

  def indirect_total
    shopping + paper_recycling + plastic_recycling + can_recycling + textile_recycling + diet + (200 * pet_cost / 30)
  end

  def shower_total
    average_shower * shower_flow_rate * household_size
  end

  def bath_total
    bath_rate * bath_multiplier * 35
  end

  def bathroom_sink_total
     bathroom_sink_usage * bathroom_sink_flow_rate * household_size
  end

  def toilet_total
    mellow * low_flow_toilet * household_size
  end

  def kitchen_total
    kitchen_sink_usage * kitchen_sink_flow_rate
  end

  def dishwashing_total
    dishwasher_rate * dishwasher_multiplier * dishwasher_method
  end

  def laundry_total
    laundry_rate * laundry_method * laundry_multiplier
  end

  def lawn_total
    lawn_rate * lawn_multiplier * lawn_size * xeriscaping
  end

  def swimming_total
    (swimming_pool / 365) + (swimming_months * 1000 / 365)
  end

  def carwash_total
    carwash_rate * carwash_multiplier * carwash_method
  end
end

class WaterusagesController < ApplicationController
  ...

  def create
    @user = User.find(params[:user_id])
    @waterusage = @user.waterusage.create(waterusage_params)
    redirect_to user_path(@user)
  end

  ...

end

答案 1 :(得分:0)

首先在create中使用'params ['和后缀']'为每个':'添加前缀,然后用'@'更改每个'_'。

就像这样:

 _powerTotal = :statewater * :percent_statewater / 100 

变成

 @powerTotal = params[:statewater].to_i * params[:percent_statewater].to_i /100

就像那样,

 :individual_total = :household_total / :household_size  

变成

 @individual_total = params[:household_total].to_i / params[:household_size].to_i

此外,您对计算没有任何作用,它们只是漂浮在原样,您甚至无法从您的视图中调用它们。

如果您希望它保存与您的waterusage对象相关的个人_total属性;

@waterusage = @user.waterusage.create(waterusage_params, individual_total: @individual_total).