HoodieOnRails
HoodieOnRails

Reputation: 248

Rails: How do I make a calculation using form input variables in the create action of a controller before saving it in the db?

In my form, the user inputs his/her weight and body fat percentage. In my controller create action, I want to calculate the lean mass of the person and save it to the lean_mass column in my db.

lean_mass = weight * (1 - body_fat)

schema.rb

create_table "stats", force: true do |t|
   t.integer  "user_id"
   t.integer  "weight"
   t.decimal  "body_fat"
   t.integer  "lean_mass"
   t.date     "date"
   t.datetime "created_at"
   t.datetime "updated_at"
 end

stats/new.html.erb

<%= form_for @stat do |f| %>
  <%= f.label :date %>
  <%= f.date_field   :date %>

  <%= f.label :weight %>
  <%= f.number_field :weight %>

  <%= f.label :body_fat %>
  <%= f.number_field :body_fat, step: 0.1 %>

  <%= f.submit %>
<% end %>

stats_controller.rb

class StatsController < ApplicationController
  before_action :authenticate_user! #I'm using devise

def index
 @stats = current_user.stats
end

def new
 @stat = current_user.stats.build
end

def create
  ##
  ###How do I calculate and add lean_mass to stat_params here?###
  ##
  @stat = current_user.stats.build(stat_params)
  if @stat.save
    redirect_to root_url, notice: "Stat was successfully created."
  else
    redirect_to dashboard_url, notice: "Problem creating stat."
  end
end

 private

 def stat_params
   params.require(:stat).permit(:date, :weight, :body_fat)
 end
end

I need help with the create action.

Upvotes: 0

Views: 1550

Answers (1)

davegson
davegson

Reputation: 8331

Manually calculate & insert the lean mass:

You will have to calculate the lean mass first:

lean_mass = params[:stat][:weight].to_i * (1 - params[:stat][:body_fat].to_i)

And then you can add it to the new @stat object

@stat = current_user.stats.build(stat_params.merge(:lean_mass => lean_mass))

# OR

@stat.lean_mass = lean_mass

Then you can go ahead and save the object.

Automatically handle the lean mass

Assuming you validate the presence of the weight & body_fat columns like so:

stat.rb

validates_presense_of :weight, :body_fat

Since the lean mass is always dependant on the weight & body_fat I'd suggest two things:

1) You can add a method lean_mass in your model that returns the calculated value, so the column would no longer be necessary.

stat.rb

def lean_mass
  self.weight * (1 - self.body_fat)
end

2) Add an after_save callback that calculates & stores the lean_mass value automatically

stat.rb

after_save { self.update(:lean_mass => self.weight * (1 - self.body_fat)) }

One of these solutions is highly suggested since you don't have to worry about the lean mass column in the create or update action.

Upvotes: 1

Related Questions