带有 MYSQL 后端的 Ruby on Rails 中虚拟属性和实例属性之间的区别
我讨厌问这样的新手问题,但我确信我正在做一些根本上错误的事情,而且我很难找到其他同样无能的人。
我的 MCMPART 模型的新视图要求用户输入零件的 :length 和 :width 值。从这些值中,我想导出 :squarefeet (:length * :width/144) 和钣金 :shearsize (:length X :width)。为此,我修改了我的模型,如下所示:
class Mcmpart < ActiveRecord::Base
belongs_to :sheet
belongs_to :partloc
belongs_to :material
def squarefeet
self.squarefeet = self.length * self.width/144
end
def shearsize
self.shearsize = [self.length, self.width].join(' X ')
end
end
控制器只是通用支架,但这里是创建方法:
def create
@mcmpart = Mcmpart.new(params[:mcmpart])
respond_to do |format|
if @mcmpart.save
format.html { redirect_to(@mcmpart, :notice => 'Mcmpart was successfully created.') }
format.xml { render :xml => @mcmpart, :status => :created, :location => @mcmpart }
else
format.html { render :action => "new" }
format.xml { render :xml => @mcmpart.errors, :status => :unprocessable_entity }
end
end
end
为了阐明模型的构造,这里是数据库迁移文件:
class CreateMcmparts < ActiveRecord::Migration
def self.up
create_table :mcmparts do |t|
t.string :partnumber
t.references :material
t.references :sheet
t.references :partloc
t.decimal :length, :precision => 10, :scale => 3
t.decimal :width, :precision => 10, :scale => 3
t.decimal :squarefeet, :precision => 10, :scale => 3
t.decimal :weight, :precision => 10, :scale => 3
t.string :shearsize
t.string :project
t.boolean :bus
t.timestamps
end
end
def self.down
drop_table :mcmparts
end
end
我相信有人会立即发现我的问题。这正在创建一个虚拟属性,该属性仅在我的 SHOW 视图中显示。但是,我想要的是将 :shearsize 和 :squarefeet 参数添加到我的数据库中。相反,我在数据库中的两个属性都得到了零值。由于它不是我需要的实例属性,因此它不受我的数据库中设置的精度/小数位数值的控制,因此在小数点后显示多达 8 位数字。
我需要在控制器中做些什么吗?我尝试用 @mcmpart.shearsize 替换 self.shearsize 但这只会导致我的页面失败。
感谢第一个指出我的菜鸟错误的人。
谢谢你,
I hate to ask such a newbie question but I am certain that I am doing something fundamentally wrong and I am having a hard time finding others out there who are as clueless.
The NEW view of my MCMPART model requires the user to enter values for :length and :width of a part. From those values, I want to derive :squarefeet (:length * :width/144) and the sheet metal :shearsize (:length X :width). To do this I have modified my model as follows:
class Mcmpart < ActiveRecord::Base
belongs_to :sheet
belongs_to :partloc
belongs_to :material
def squarefeet
self.squarefeet = self.length * self.width/144
end
def shearsize
self.shearsize = [self.length, self.width].join(' X ')
end
end
The controller is just generic scaffold but here is the create method:
def create
@mcmpart = Mcmpart.new(params[:mcmpart])
respond_to do |format|
if @mcmpart.save
format.html { redirect_to(@mcmpart, :notice => 'Mcmpart was successfully created.') }
format.xml { render :xml => @mcmpart, :status => :created, :location => @mcmpart }
else
format.html { render :action => "new" }
format.xml { render :xml => @mcmpart.errors, :status => :unprocessable_entity }
end
end
end
To clarify the construction of the model, here is the database migration file:
class CreateMcmparts < ActiveRecord::Migration
def self.up
create_table :mcmparts do |t|
t.string :partnumber
t.references :material
t.references :sheet
t.references :partloc
t.decimal :length, :precision => 10, :scale => 3
t.decimal :width, :precision => 10, :scale => 3
t.decimal :squarefeet, :precision => 10, :scale => 3
t.decimal :weight, :precision => 10, :scale => 3
t.string :shearsize
t.string :project
t.boolean :bus
t.timestamps
end
end
def self.down
drop_table :mcmparts
end
end
I am sure someone will spot my problem right away. This is creating a virtual attribute that displays just find in my SHOW view. However, what I want is for this to add the :shearsize and :squarefeet params to my database. Instead I am getting a nil value for both attributes in my database. And since it is not an instance attribute as I require, it is not governed by the precision/scale values set in my database and therefore displays as many as 8 digits after the decimal point.
Is there something I need to do in the controller? I have tried to replace self.shearsize with @mcmpart.shearsize but that just causes my pages to fail.
Kudos to the first person to point out my rookie error(s).
Thank you,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
基于以下假设,我正在尝试解决您的问题。
首先将这些线添加到您的 Mcmpart 模型中
,这就是添加这些线后您的模型应该是什么样子。
这现在应该可以工作了。如果没有,那么我需要更多细节,因为我不清楚。如果能贴出controller和model(完整代码)就更好了。
Based on following assumption I am trying to solve your problem.
First add these lines to your Mcmpart model
So this is how your model should look like after these additions.
This should be working now. If it does not then I need more detail as it is unclear to me. It would be better if you can post controller and model (complete code).
我能看到你的困惑
shehersize 和 squarefeet 都是计算值,对吗?
他们在你的观点中发挥作用,对吗?
那么您想要将它们存储在数据库中的唯一原因是为了可以正确地格式化它们?
如果上述假设正确,那么您不需要将它们存储在数据库中,您可以在计算它们时对其进行格式化,并且有各种视图助手来限制显示的小数位数。
我不知道你想显示多少个小数点,但如果你想显示 2 个小数位,你可以尝试将
.2f 更改为 .4f,如果你想要 4 个小数位,或者你想要的任何小数位,
如果你有如果有其他原因将数据存储在数据库中,那么我建议您使用保存过滤器并在其中进行计算。如果您想了解更多信息,请询问
I can see your confusion
sheersize and squarefeet are both calculated values right?
They work in your views right?
So the only reason you want to store them in your database is so that you can format them right?
If the above assumptions are correct then you don't need to store them in your database you can format them as you calculate them and there are various view helpers to restrict the number of decimal points shown.
I have no idea how many decimal points you want to show but if you wanted to show 2 decimal places you could try this
change .2f to .4f if you wanted 4 decimal places or whatever number of decimal places you want to have
If you have other reasons for storing the data in the database then I suggest you use an on save filter and do the calulations in there. If you want more info on that then ask