Using: Ruby on Rails (3.0.3)
I am building a website where one can perform different health and diet related calculations.
Each calculation holds different inputs:
Calculation 1 height, weight, waist_measurement
Calculation 2 weight, hip_measurement
Calculation 3 hip_measurement, lifestyle_type (string), age, calory_intake
...and so on.
I have (as a suggestion from a friend who knows RoR) created a model "Calculation" (which stands as a template) and another model "CalculationSheet" that will be used as an instance model etc.
Model:Calculation (the template) holds data like: - TypeOfCalculation ('health', 'lifestyle' etc) - SearchTags - isSpecial (a boolean to isolate certain special Calculations)
There are as many Calculation objects as there are calculation "types" on the website (such as the 3 I mentioned earlier)
Model: CalculationSheet will only hold data like: - Result (such as BMI=>22)
A CalculationSheet will be created when a calculation is performed on the website using Create. I have no need to save these calculations (prefer not to actually).
The most important reason for using the CalculationSheet model is to be able to validate the input...and here is the problem.
Problem: How do I validate inputs from a model that does not hold each input as an attribute. I cannot make an attribute for each type of input (there are literally 100's), such as height, weight, life_style, waist, age etc...
This is my plan as for now:
class CalculationSheet < ActiveRecord::Base
belongs_to :calculation
# BMI
validates :height, :numericality => true, :if => :calculation_is_bmi?
validates :weight, :numericality => true, :if => :calculation_is_bmi?
def calculation_is_bmi?
# do something
end
end
which (obviously) does not work开发者_Python百科. It tries to validate height which does not exist.
What I would like to do is to "validates params[:height], :numer... etc" but it does not seem to work either...
How can I solve this?
You can use ActiveModel
instead of ActiveRecord
as shown in these lines:
class CalculationSheet
include ActiveModel::Validations
attr_accessor :height, :weight
validates_numericality_of :height, :weight
end
This will allow for form validation of every attribute, but you don't store anything. Here's a great post by Yehuda Katz about ActiveModel
: ActiveModel: Make Any Ruby Object Feel Like ActiveRecord
For Rails 3 use validates_with
to use a custom validator.
See this great post for information on how to use them.
edit:
How about this:
class CalculationSheet
include ActiveModel::Validations
attr_accessor :height, :weight, :hip_circumference
validates_numericality_of :height, :weight, :if => :bmi?
validates_numericality_of :height, :hip_circumference, :if => :bai?
def bmi?
[height, weight].all?(&:present?)
end
def bmi
weight / (height**2)
end
def bai?
[height, :hip_circumference].all?(&:present?)
end
def bai
(hip_circumference / height**1.5) − 18
end
end
The trick is in your comment "I have no need to save these calculations":
ActiveRecord is all about providing persistence for your data (i.e. saving). If you're just wanting to do calculations, you can use plain old ruby objects :)
With stuff like this I'd be tempted to build a little library (perhaps in /lib now and as a gem later) that does your calculations.
精彩评论