2010-12-01 88 views
0

我有以下型号:Ruby on Rails的 - 虚拟属性

create_table "material_costs", :force => true do |t| 
    t.string "material" 
    t.integer "height" 
    t.integer "width" 
    t.decimal "cost",  :precision => 4, :scale => 2 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

我将如何创建模型虚拟属性来给我按每种材料的平方英寸的成本是多少?

而且我已经持有增值税值另一种模式:

create_table "taxes", :force => true do |t| 
    t.string "name" 
    t.decimal "rate",  :precision => 10, :scale => 0 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

如何使用这个模型来给我每平方英寸的总价格为每一种材料项目,即需要对增值税率增加?

编辑 - 我现在存储在以下模型增值税值:

create_table "app_options", :force => true do |t| 
    t.string "name" 
    t.string "value" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

编辑 - 这是我的控制器代码:

def calculate_quote 
    @moulding = Moulding.find(params[:id], :select => 'cost, width') 
    @mount = MaterialCost.find(1).total_cost_per_square_mm 
    @glass = MaterialCost.find(2).total_cost_per_square_mm 
    @backing_board = MaterialCost.find(3).total_cost_per_square_mm 
    @wastage = AppOption.find(2, :select => 'value') 
    @markup = AppOption.find(3, :select => 'value') 

    respond_to do |format| 
     format.json { render :json => { :moulding => @moulding, :mount => @mount, :glass => @glass, :backing_board => @backing_board, :wastage => @wastage, :markup => @markup } } 
    end 
    end 

回答

3

把它放在表中或者每次更新时都需要重新计算它并没有意义。按照Matchu的建议,您应该在模型类中定义一个方法。

注:我已经添加了一个类变量来保存税值。

class MaterialCost < ActiveRecord::Base 
    # Initialize the tax rate on initialization of the class 
    @@tax = AppOptions.find(:first, :name => 'VAT').value.to_f 

    # ... 

    def base_cost_per_square_inch 
    cost/(height * width) 
    end 

    def total_cost_per_square_inch 
    base_cost_per_square_inch * (1 + @@tax) 
    end 
end 

和一些控制器代码:

class MaterialsController < ApplicationController 

    def calculate_full_price 
    # GET /Materials/calculate_full_price/5 

    # Get the material in question using the ID param. 
    material = MaterialCost.find(:first, :id => params[:id]) 

    # Calculate the total price 
    @total_price_per_sq_in_with_tax = material.total_cost_per_square_inch 

    # Done (fall off to render the normal view) 
    end 

end 

我不太确定你的税用例到底是什么,但是,让更多一点意义吗?

0

这不是真的每一个虚拟属性这只是一种方法,对吧?

def cost_per_square_inch 
    cost/height/width 
end 
+0

当我尝试在控制器中使用类似`@mount = MaterialCost.find(1,:select =>'cost_per_square_mm')的方式提取这些数据时,我得到未知列'cost_per_square_mm'错误? – freshest 2010-12-01 16:14:42

+0

您不能使用查找器查找虚拟属性。它们是虚拟的 - 也就是说,只要模型存在于内存中,它们就只存在于模型中,而不是存储在模型中的数据(例如数据库表中的行)。 – yfeldblum 2010-12-01 16:19:14