开发者

Rails: Model and model template interaction

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜